summaryrefslogtreecommitdiffstats
path: root/lib/public/AppFramework
diff options
context:
space:
mode:
Diffstat (limited to 'lib/public/AppFramework')
-rw-r--r--lib/public/AppFramework/ApiController.php96
-rw-r--r--lib/public/AppFramework/App.php136
-rw-r--r--lib/public/AppFramework/Controller.php263
-rw-r--r--lib/public/AppFramework/Db/DoesNotExistException.php43
-rw-r--r--lib/public/AppFramework/Db/Entity.php253
-rw-r--r--lib/public/AppFramework/Db/Mapper.php376
-rw-r--r--lib/public/AppFramework/Db/MultipleObjectsReturnedException.php43
-rw-r--r--lib/public/AppFramework/Http.php96
-rw-r--r--lib/public/AppFramework/Http/ContentSecurityPolicy.php88
-rw-r--r--lib/public/AppFramework/Http/DataDisplayResponse.php88
-rw-r--r--lib/public/AppFramework/Http/DataDownloadResponse.php63
-rw-r--r--lib/public/AppFramework/Http/DataResponse.php83
-rw-r--r--lib/public/AppFramework/Http/DownloadResponse.php52
-rw-r--r--lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php385
-rw-r--r--lib/public/AppFramework/Http/ICallbackResponse.php43
-rw-r--r--lib/public/AppFramework/Http/IOutput.php77
-rw-r--r--lib/public/AppFramework/Http/JSONResponse.php100
-rw-r--r--lib/public/AppFramework/Http/NotFoundResponse.php49
-rw-r--r--lib/public/AppFramework/Http/OCSResponse.php91
-rw-r--r--lib/public/AppFramework/Http/RedirectResponse.php61
-rw-r--r--lib/public/AppFramework/Http/Response.php326
-rw-r--r--lib/public/AppFramework/Http/StreamResponse.php64
-rw-r--r--lib/public/AppFramework/Http/TemplateResponse.php159
-rw-r--r--lib/public/AppFramework/IApi.php97
-rw-r--r--lib/public/AppFramework/IAppContainer.php97
-rw-r--r--lib/public/AppFramework/Middleware.php110
-rw-r--r--lib/public/AppFramework/OCSController.php102
-rw-r--r--lib/public/AppFramework/QueryException.php33
-rw-r--r--lib/public/AppFramework/Utility/IControllerMethodReflector.php70
-rw-r--r--lib/public/AppFramework/Utility/ITimeFactory.php39
30 files changed, 3583 insertions, 0 deletions
diff --git a/lib/public/AppFramework/ApiController.php b/lib/public/AppFramework/ApiController.php
new file mode 100644
index 00000000000..07b72d9a46c
--- /dev/null
+++ b/lib/public/AppFramework/ApiController.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\Controller class
+ */
+
+namespace OCP\AppFramework;
+
+use OCP\AppFramework\Http\Response;
+use OCP\IRequest;
+
+
+/**
+ * Base class to inherit your controllers from that are used for RESTful APIs
+ * @since 7.0.0
+ */
+abstract class ApiController extends Controller {
+
+ private $corsMethods;
+ private $corsAllowedHeaders;
+ private $corsMaxAge;
+
+ /**
+ * constructor of the controller
+ * @param string $appName the name of the app
+ * @param IRequest $request an instance of the request
+ * @param string $corsMethods comma separated string of HTTP verbs which
+ * should be allowed for websites or webapps when calling your API, defaults to
+ * 'PUT, POST, GET, DELETE, PATCH'
+ * @param string $corsAllowedHeaders comma separated string of HTTP headers
+ * which should be allowed for websites or webapps when calling your API,
+ * defaults to 'Authorization, Content-Type, Accept'
+ * @param int $corsMaxAge number in seconds how long a preflighted OPTIONS
+ * request should be cached, defaults to 1728000 seconds
+ * @since 7.0.0
+ */
+ public function __construct($appName,
+ IRequest $request,
+ $corsMethods='PUT, POST, GET, DELETE, PATCH',
+ $corsAllowedHeaders='Authorization, Content-Type, Accept',
+ $corsMaxAge=1728000){
+ parent::__construct($appName, $request);
+ $this->corsMethods = $corsMethods;
+ $this->corsAllowedHeaders = $corsAllowedHeaders;
+ $this->corsMaxAge = $corsMaxAge;
+ }
+
+
+ /**
+ * This method implements a preflighted cors response for you that you can
+ * link to for the options request
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ * @PublicPage
+ * @since 7.0.0
+ */
+ public function preflightedCors() {
+ if(isset($this->request->server['HTTP_ORIGIN'])) {
+ $origin = $this->request->server['HTTP_ORIGIN'];
+ } else {
+ $origin = '*';
+ }
+
+ $response = new Response();
+ $response->addHeader('Access-Control-Allow-Origin', $origin);
+ $response->addHeader('Access-Control-Allow-Methods', $this->corsMethods);
+ $response->addHeader('Access-Control-Max-Age', $this->corsMaxAge);
+ $response->addHeader('Access-Control-Allow-Headers', $this->corsAllowedHeaders);
+ $response->addHeader('Access-Control-Allow-Credentials', 'false');
+ return $response;
+ }
+
+
+}
diff --git a/lib/public/AppFramework/App.php b/lib/public/AppFramework/App.php
new file mode 100644
index 00000000000..e5069150765
--- /dev/null
+++ b/lib/public/AppFramework/App.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework/App class
+ */
+
+namespace OCP\AppFramework;
+use OC\AppFramework\Routing\RouteConfig;
+
+
+/**
+ * Class App
+ * @package OCP\AppFramework
+ *
+ * Any application must inherit this call - all controller instances to be used are
+ * to be registered using IContainer::registerService
+ * @since 6.0.0
+ */
+class App {
+
+
+ /**
+ * Turns an app id into a namespace by convetion. The id is split at the
+ * underscores, all parts are camelcased and reassembled. e.g.:
+ * some_app_id -> OCA\SomeAppId
+ * @param string $appId the app id
+ * @param string $topNamespace the namespace which should be prepended to
+ * the transformed app id, defaults to OCA\
+ * @return string the starting namespace for the app
+ * @since 8.0.0
+ */
+ public static function buildAppNamespace($appId, $topNamespace='OCA\\') {
+ return \OC\AppFramework\App::buildAppNamespace($appId, $topNamespace);
+ }
+
+
+ /**
+ * @param array $urlParams an array with variables extracted from the routes
+ * @since 6.0.0
+ */
+ public function __construct($appName, $urlParams = array()) {
+ $this->container = new \OC\AppFramework\DependencyInjection\DIContainer($appName, $urlParams);
+ }
+
+ private $container;
+
+ /**
+ * @return IAppContainer
+ * @since 6.0.0
+ */
+ public function getContainer() {
+ return $this->container;
+ }
+
+ /**
+ * This function is to be called to create single routes and restful routes based on the given $routes array.
+ *
+ * Example code in routes.php of tasks app (it will register two restful resources):
+ * $routes = array(
+ * 'resources' => array(
+ * 'lists' => array('url' => '/tasklists'),
+ * 'tasks' => array('url' => '/tasklists/{listId}/tasks')
+ * )
+ * );
+ *
+ * $a = new TasksApp();
+ * $a->registerRoutes($this, $routes);
+ *
+ * @param \OCP\Route\IRouter $router
+ * @param array $routes
+ * @since 6.0.0
+ */
+ public function registerRoutes($router, $routes) {
+ $routeConfig = new RouteConfig($this->container, $router, $routes);
+ $routeConfig->register();
+ }
+
+ /**
+ * This function is called by the routing component to fire up the frameworks dispatch mechanism.
+ *
+ * Example code in routes.php of the task app:
+ * $this->create('tasks_index', '/')->get()->action(
+ * function($params){
+ * $app = new TaskApp($params);
+ * $app->dispatch('PageController', 'index');
+ * }
+ * );
+ *
+ *
+ * Example for for TaskApp implementation:
+ * class TaskApp extends \OCP\AppFramework\App {
+ *
+ * public function __construct($params){
+ * parent::__construct('tasks', $params);
+ *
+ * $this->getContainer()->registerService('PageController', function(IAppContainer $c){
+ * $a = $c->query('API');
+ * $r = $c->query('Request');
+ * return new PageController($a, $r);
+ * });
+ * }
+ * }
+ *
+ * @param string $controllerName the name of the controller under which it is
+ * stored in the DI container
+ * @param string $methodName the method that you want to call
+ * @since 6.0.0
+ */
+ public function dispatch($controllerName, $methodName) {
+ \OC\AppFramework\App::main($controllerName, $methodName, $this->container);
+ }
+}
diff --git a/lib/public/AppFramework/Controller.php b/lib/public/AppFramework/Controller.php
new file mode 100644
index 00000000000..bd87197a7f1
--- /dev/null
+++ b/lib/public/AppFramework/Controller.php
@@ -0,0 +1,263 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\Controller class
+ */
+
+namespace OCP\AppFramework;
+
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\Response;
+use OCP\IRequest;
+
+
+/**
+ * Base class to inherit your controllers from
+ * @since 6.0.0
+ */
+abstract class Controller {
+
+ /**
+ * app name
+ * @var string
+ * @since 7.0.0
+ */
+ protected $appName;
+
+ /**
+ * current request
+ * @var \OCP\IRequest
+ * @since 6.0.0
+ */
+ protected $request;
+
+ /**
+ * @var array
+ * @since 7.0.0
+ */
+ private $responders;
+
+ /**
+ * constructor of the controller
+ * @param string $appName the name of the app
+ * @param IRequest $request an instance of the request
+ * @since 6.0.0 - parameter $appName was added in 7.0.0 - parameter $app was removed in 7.0.0
+ */
+ public function __construct($appName,
+ IRequest $request) {
+ $this->appName = $appName;
+ $this->request = $request;
+
+ // default responders
+ $this->responders = array(
+ 'json' => function ($data) {
+ if ($data instanceof DataResponse) {
+ $response = new JSONResponse(
+ $data->getData(),
+ $data->getStatus()
+ );
+ $dataHeaders = $data->getHeaders();
+ $headers = $response->getHeaders();
+ // do not overwrite Content-Type if it already exists
+ if (isset($dataHeaders['Content-Type'])) {
+ unset($headers['Content-Type']);
+ }
+ $response->setHeaders(array_merge($dataHeaders, $headers));
+ return $response;
+ } else {
+ return new JSONResponse($data);
+ }
+ }
+ );
+ }
+
+
+ /**
+ * Parses an HTTP accept header and returns the supported responder type
+ * @param string $acceptHeader
+ * @return string the responder type
+ * @since 7.0.0
+ */
+ public function getResponderByHTTPHeader($acceptHeader) {
+ $headers = explode(',', $acceptHeader);
+
+ // return the first matching responder
+ foreach ($headers as $header) {
+ $header = strtolower(trim($header));
+
+ $responder = str_replace('application/', '', $header);
+
+ if (array_key_exists($responder, $this->responders)) {
+ return $responder;
+ }
+ }
+
+ // no matching header defaults to json
+ return 'json';
+ }
+
+
+ /**
+ * Registers a formatter for a type
+ * @param string $format
+ * @param \Closure $responder
+ * @since 7.0.0
+ */
+ 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
+ * @since 7.0.0
+ */
+ public function buildResponse($response, $format='json') {
+ if(array_key_exists($format, $this->responders)) {
+
+ $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 7.0.0 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:
+ * 1. URL parameters
+ * 2. POST parameters
+ * 3. GET parameters
+ * @param string $default If the key is not found, this value will be returned
+ * @return mixed the content of the array
+ * @since 6.0.0
+ */
+ public function params($key, $default=null){
+ return $this->request->getParam($key, $default);
+ }
+
+
+ /**
+ * Returns all params that were received, be it from the request
+ * (as GET or POST) or through the URL by the route
+ * @deprecated 7.0.0 use $this->request instead
+ * @return array the array with all parameters
+ * @since 6.0.0
+ */
+ public function getParams() {
+ return $this->request->getParams();
+ }
+
+
+ /**
+ * Returns the method of the request
+ * @deprecated 7.0.0 use $this->request instead
+ * @return string the method of the request (POST, GET, etc)
+ * @since 6.0.0
+ */
+ public function method() {
+ return $this->request->getMethod();
+ }
+
+
+ /**
+ * Shortcut for accessing an uploaded file through the $_FILES array
+ * @deprecated 7.0.0 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
+ * @since 6.0.0
+ */
+ public function getUploadedFile($key) {
+ return $this->request->getUploadedFile($key);
+ }
+
+
+ /**
+ * Shortcut for getting env variables
+ * @deprecated 7.0.0 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
+ * @since 6.0.0
+ */
+ public function env($key) {
+ return $this->request->getEnv($key);
+ }
+
+
+ /**
+ * Shortcut for getting cookie variables
+ * @deprecated 7.0.0 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
+ * @since 6.0.0
+ */
+ public function cookie($key) {
+ return $this->request->getCookie($key);
+ }
+
+
+ /**
+ * Shortcut for rendering a template
+ * @deprecated 7.0.0 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
+ * admin an entry in the admin settings
+ * @param string[] $headers set additional headers in name/value pairs
+ * @return \OCP\AppFramework\Http\TemplateResponse containing the page
+ * @since 6.0.0
+ */
+ public function render($templateName, array $params=array(),
+ $renderAs='user', array $headers=array()){
+ $response = new TemplateResponse($this->appName, $templateName);
+ $response->setParams($params);
+ $response->renderAs($renderAs);
+
+ foreach($headers as $name => $value){
+ $response->addHeader($name, $value);
+ }
+
+ return $response;
+ }
+
+
+}
diff --git a/lib/public/AppFramework/Db/DoesNotExistException.php b/lib/public/AppFramework/Db/DoesNotExistException.php
new file mode 100644
index 00000000000..9682a08d3cf
--- /dev/null
+++ b/lib/public/AppFramework/Db/DoesNotExistException.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCP\AppFramework\Db;
+
+
+/**
+ * This is returned or should be returned when a find request does not find an
+ * entry in the database
+ * @since 7.0.0
+ */
+class DoesNotExistException extends \Exception {
+
+ /**
+ * Constructor
+ * @param string $msg the error message
+ * @since 7.0.0
+ */
+ public function __construct($msg){
+ parent::__construct($msg);
+ }
+
+}
diff --git a/lib/public/AppFramework/Db/Entity.php b/lib/public/AppFramework/Db/Entity.php
new file mode 100644
index 00000000000..d7db4d3c5a7
--- /dev/null
+++ b/lib/public/AppFramework/Db/Entity.php
@@ -0,0 +1,253 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Db;
+
+
+/**
+ * @method integer getId()
+ * @method void setId(integer $id)
+ * @since 7.0.0
+ */
+abstract class Entity {
+
+ public $id;
+
+ private $_updatedFields = array();
+ private $_fieldTypes = array('id' => 'integer');
+
+
+ /**
+ * Simple alternative constructor for building entities from a request
+ * @param array $params the array which was obtained via $this->params('key')
+ * in the controller
+ * @return Entity
+ * @since 7.0.0
+ */
+ public static function fromParams(array $params) {
+ $instance = new static();
+
+ foreach($params as $key => $value) {
+ $method = 'set' . ucfirst($key);
+ $instance->$method($value);
+ }
+
+ return $instance;
+ }
+
+
+ /**
+ * Maps the keys of the row array to the attributes
+ * @param array $row the row to map onto the entity
+ * @since 7.0.0
+ */
+ public static function fromRow(array $row){
+ $instance = new static();
+
+ foreach($row as $key => $value){
+ $prop = ucfirst($instance->columnToProperty($key));
+ $setter = 'set' . $prop;
+ $instance->$setter($value);
+ }
+
+ $instance->resetUpdatedFields();
+
+ return $instance;
+ }
+
+
+ /**
+ * @return array with attribute and type
+ * @since 7.0.0
+ */
+ public function getFieldTypes() {
+ return $this->_fieldTypes;
+ }
+
+
+ /**
+ * Marks the entity as clean needed for setting the id after the insertion
+ * @since 7.0.0
+ */
+ public function resetUpdatedFields(){
+ $this->_updatedFields = array();
+ }
+
+ /**
+ * Generic setter for properties
+ * @since 7.0.0
+ */
+ protected function setter($name, $args) {
+ // setters should only work for existing attributes
+ if(property_exists($this, $name)){
+ if($this->$name === $args[0]) {
+ return;
+ }
+ $this->markFieldUpdated($name);
+
+ // if type definition exists, cast to correct type
+ if($args[0] !== null && array_key_exists($name, $this->_fieldTypes)) {
+ settype($args[0], $this->_fieldTypes[$name]);
+ }
+ $this->$name = $args[0];
+
+ } else {
+ throw new \BadFunctionCallException($name .
+ ' is not a valid attribute');
+ }
+ }
+
+ /**
+ * Generic getter for properties
+ * @since 7.0.0
+ */
+ protected function getter($name) {
+ // getters should only work for existing attributes
+ if(property_exists($this, $name)){
+ return $this->$name;
+ } else {
+ throw new \BadFunctionCallException($name .
+ ' is not a valid attribute');
+ }
+ }
+
+
+ /**
+ * Each time a setter is called, push the part after set
+ * into an array: for instance setId will save Id in the
+ * updated fields array so it can be easily used to create the
+ * getter method
+ * @since 7.0.0
+ */
+ public function __call($methodName, $args){
+ $attr = lcfirst( substr($methodName, 3) );
+
+ if(strpos($methodName, 'set') === 0){
+ $this->setter($attr, $args);
+ } elseif(strpos($methodName, 'get') === 0) {
+ return $this->getter($attr);
+ } else {
+ throw new \BadFunctionCallException($methodName .
+ ' does not exist');
+ }
+
+ }
+
+
+ /**
+ * Mark am attribute as updated
+ * @param string $attribute the name of the attribute
+ * @since 7.0.0
+ */
+ protected function markFieldUpdated($attribute){
+ $this->_updatedFields[$attribute] = true;
+ }
+
+
+ /**
+ * Transform a database columnname to a property
+ * @param string $columnName the name of the column
+ * @return string the property name
+ * @since 7.0.0
+ */
+ public function columnToProperty($columnName){
+ $parts = explode('_', $columnName);
+ $property = null;
+
+ foreach($parts as $part){
+ if($property === null){
+ $property = $part;
+ } else {
+ $property .= ucfirst($part);
+ }
+ }
+
+ return $property;
+ }
+
+
+ /**
+ * Transform a property to a database column name
+ * @param string $property the name of the property
+ * @return string the column name
+ * @since 7.0.0
+ */
+ public function propertyToColumn($property){
+ $parts = preg_split('/(?=[A-Z])/', $property);
+ $column = null;
+
+ foreach($parts as $part){
+ if($column === null){
+ $column = $part;
+ } else {
+ $column .= '_' . lcfirst($part);
+ }
+ }
+
+ return $column;
+ }
+
+
+ /**
+ * @return array array of updated fields for update query
+ * @since 7.0.0
+ */
+ public function getUpdatedFields(){
+ return $this->_updatedFields;
+ }
+
+
+ /**
+ * Adds type information for a field so that its automatically casted to
+ * that value once its being returned from the database
+ * @param string $fieldName the name of the attribute
+ * @param string $type the type which will be used to call settype()
+ * @since 7.0.0
+ */
+ protected function addType($fieldName, $type){
+ $this->_fieldTypes[$fieldName] = $type;
+ }
+
+
+ /**
+ * Slugify the value of a given attribute
+ * Warning: This doesn't result in a unique value
+ * @param string $attributeName the name of the attribute, which value should be slugified
+ * @return string slugified value
+ * @since 7.0.0
+ */
+ public function slugify($attributeName){
+ // toSlug should only work for existing attributes
+ if(property_exists($this, $attributeName)){
+ $value = $this->$attributeName;
+ // replace everything except alphanumeric with a single '-'
+ $value = preg_replace('/[^A-Za-z0-9]+/', '-', $value);
+ $value = strtolower($value);
+ // trim '-'
+ return trim($value, '-');
+ } else {
+ throw new \BadFunctionCallException($attributeName .
+ ' is not a valid attribute');
+ }
+ }
+
+}
diff --git a/lib/public/AppFramework/Db/Mapper.php b/lib/public/AppFramework/Db/Mapper.php
new file mode 100644
index 00000000000..2e97b06802a
--- /dev/null
+++ b/lib/public/AppFramework/Db/Mapper.php
@@ -0,0 +1,376 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCP\AppFramework\Db;
+
+use OCP\IDBConnection;
+use OCP\IDb;
+
+
+/**
+ * Simple parent class for inheriting your data access layer from. This class
+ * may be subject to change in the future
+ * @since 7.0.0
+ */
+abstract class Mapper {
+
+ protected $tableName;
+ protected $entityClass;
+ protected $db;
+
+ /**
+ * @param IDBConnection $db Instance of the Db abstraction layer
+ * @param string $tableName the name of the table. set this to allow entity
+ * @param string $entityClass the name of the entity that the sql should be
+ * mapped to queries without using sql
+ * @since 7.0.0
+ */
+ public function __construct(IDBConnection $db, $tableName, $entityClass=null){
+ $this->db = $db;
+ $this->tableName = '*PREFIX*' . $tableName;
+
+ // if not given set the entity name to the class without the mapper part
+ // cache it here for later use since reflection is slow
+ if($entityClass === null) {
+ $this->entityClass = str_replace('Mapper', '', get_class($this));
+ } else {
+ $this->entityClass = $entityClass;
+ }
+ }
+
+
+ /**
+ * @return string the table name
+ * @since 7.0.0
+ */
+ public function getTableName(){
+ return $this->tableName;
+ }
+
+
+ /**
+ * Deletes an entity from the table
+ * @param Entity $entity the entity that should be deleted
+ * @return Entity the deleted entity
+ * @since 7.0.0 - return value added in 8.1.0
+ */
+ public function delete(Entity $entity){
+ $sql = 'DELETE FROM `' . $this->tableName . '` WHERE `id` = ?';
+ $stmt = $this->execute($sql, [$entity->getId()]);
+ $stmt->closeCursor();
+ return $entity;
+ }
+
+
+ /**
+ * Creates a new entry in the db from an entity
+ * @param Entity $entity the entity that should be created
+ * @return Entity the saved entity with the set id
+ * @since 7.0.0
+ */
+ public function insert(Entity $entity){
+ // get updated fields to save, fields have to be set using a setter to
+ // be saved
+ $properties = $entity->getUpdatedFields();
+ $values = '';
+ $columns = '';
+ $params = [];
+
+ // build the fields
+ $i = 0;
+ foreach($properties as $property => $updated) {
+ $column = $entity->propertyToColumn($property);
+ $getter = 'get' . ucfirst($property);
+
+ $columns .= '`' . $column . '`';
+ $values .= '?';
+
+ // only append colon if there are more entries
+ if($i < count($properties)-1){
+ $columns .= ',';
+ $values .= ',';
+ }
+
+ $params[] = $entity->$getter();
+ $i++;
+
+ }
+
+ $sql = 'INSERT INTO `' . $this->tableName . '`(' .
+ $columns . ') VALUES(' . $values . ')';
+
+ $stmt = $this->execute($sql, $params);
+
+ $entity->setId((int) $this->db->lastInsertId($this->tableName));
+
+ $stmt->closeCursor();
+
+ return $entity;
+ }
+
+
+
+ /**
+ * Updates an entry in the db from an entity
+ * @throws \InvalidArgumentException if entity has no id
+ * @param Entity $entity the entity that should be created
+ * @return Entity the saved entity with the set id
+ * @since 7.0.0 - return value was added in 8.0.0
+ */
+ public function update(Entity $entity){
+ // if entity wasn't changed it makes no sense to run a db query
+ $properties = $entity->getUpdatedFields();
+ if(count($properties) === 0) {
+ return $entity;
+ }
+
+ // entity needs an id
+ $id = $entity->getId();
+ if($id === null){
+ throw new \InvalidArgumentException(
+ 'Entity which should be updated has no id');
+ }
+
+ // get updated fields to save, fields have to be set using a setter to
+ // be saved
+ // do not update the id field
+ unset($properties['id']);
+
+ $columns = '';
+ $params = [];
+
+ // build the fields
+ $i = 0;
+ foreach($properties as $property => $updated) {
+
+ $column = $entity->propertyToColumn($property);
+ $getter = 'get' . ucfirst($property);
+
+ $columns .= '`' . $column . '` = ?';
+
+ // only append colon if there are more entries
+ if($i < count($properties)-1){
+ $columns .= ',';
+ }
+
+ $params[] = $entity->$getter();
+ $i++;
+ }
+
+ $sql = 'UPDATE `' . $this->tableName . '` SET ' .
+ $columns . ' WHERE `id` = ?';
+ $params[] = $id;
+
+ $stmt = $this->execute($sql, $params);
+ $stmt->closeCursor();
+
+ return $entity;
+ }
+
+ /**
+ * Checks if an array is associative
+ * @param array $array
+ * @return bool true if associative
+ * @since 8.1.0
+ */
+ private function isAssocArray(array $array) {
+ return array_values($array) !== $array;
+ }
+
+ /**
+ * Returns the correct PDO constant based on the value type
+ * @param $value
+ * @return int PDO constant
+ * @since 8.1.0
+ */
+ private function getPDOType($value) {
+ switch (gettype($value)) {
+ case 'integer':
+ return \PDO::PARAM_INT;
+ case 'boolean':
+ return \PDO::PARAM_BOOL;
+ default:
+ return \PDO::PARAM_STR;
+ }
+ }
+
+
+ /**
+ * Runs an sql query
+ * @param string $sql the prepare string
+ * @param array $params the params which should replace the ? in the sql query
+ * @param int $limit the maximum number of rows
+ * @param int $offset from which row we want to start
+ * @return \PDOStatement the database query result
+ * @since 7.0.0
+ */
+ protected function execute($sql, array $params=[], $limit=null, $offset=null){
+ if ($this->db instanceof IDb) {
+ $query = $this->db->prepareQuery($sql, $limit, $offset);
+ } else {
+ $query = $this->db->prepare($sql, $limit, $offset);
+ }
+
+ if ($this->isAssocArray($params)) {
+ foreach ($params as $key => $param) {
+ $pdoConstant = $this->getPDOType($param);
+ $query->bindValue($key, $param, $pdoConstant);
+ }
+ } else {
+ $index = 1; // bindParam is 1 indexed
+ foreach ($params as $param) {
+ $pdoConstant = $this->getPDOType($param);
+ $query->bindValue($index, $param, $pdoConstant);
+ $index++;
+ }
+ }
+
+ $result = $query->execute();
+
+ // this is only for backwards compatibility reasons and can be removed
+ // in owncloud 10. IDb returns a StatementWrapper from execute, PDO,
+ // Doctrine and IDbConnection don't so this needs to be done in order
+ // to stay backwards compatible for the things that rely on the
+ // StatementWrapper being returned
+ if ($result instanceof \OC_DB_StatementWrapper) {
+ return $result;
+ }
+
+ return $query;
+ }
+
+
+ /**
+ * Returns an db result and throws exceptions when there are more or less
+ * results
+ * @see findEntity
+ * @param string $sql the sql query
+ * @param array $params the parameters of the sql query
+ * @param int $limit the maximum number of rows
+ * @param int $offset from which row we want to start
+ * @throws DoesNotExistException if the item does not exist
+ * @throws MultipleObjectsReturnedException if more than one item exist
+ * @return array the result as row
+ * @since 7.0.0
+ */
+ protected function findOneQuery($sql, array $params=[], $limit=null, $offset=null){
+ $stmt = $this->execute($sql, $params, $limit, $offset);
+ $row = $stmt->fetch();
+
+ if($row === false || $row === null){
+ $stmt->closeCursor();
+ $msg = $this->buildDebugMessage(
+ 'Did expect one result but found none when executing', $sql, $params, $limit, $offset
+ );
+ throw new DoesNotExistException($msg);
+ }
+ $row2 = $stmt->fetch();
+ $stmt->closeCursor();
+ //MDB2 returns null, PDO and doctrine false when no row is available
+ if( ! ($row2 === false || $row2 === null )) {
+ $msg = $this->buildDebugMessage(
+ 'Did not expect more than one result when executing', $sql, $params, $limit, $offset
+ );
+ throw new MultipleObjectsReturnedException($msg);
+ } else {
+ return $row;
+ }
+ }
+
+ /**
+ * Builds an error message by prepending the $msg to an error message which
+ * has the parameters
+ * @see findEntity
+ * @param string $sql the sql query
+ * @param array $params the parameters of the sql query
+ * @param int $limit the maximum number of rows
+ * @param int $offset from which row we want to start
+ * @return string formatted error message string
+ * @since 9.1.0
+ */
+ private function buildDebugMessage($msg, $sql, array $params=[], $limit=null, $offset=null) {
+ return $msg .
+ ': query "' . $sql . '"; ' .
+ 'parameters ' . print_r($params, true) . '; ' .
+ 'limit "' . $limit . '"; '.
+ 'offset "' . $offset . '"';
+ }
+
+
+ /**
+ * Creates an entity from a row. Automatically determines the entity class
+ * from the current mapper name (MyEntityMapper -> MyEntity)
+ * @param array $row the row which should be converted to an entity
+ * @return Entity the entity
+ * @since 7.0.0
+ */
+ protected function mapRowToEntity($row) {
+ return call_user_func($this->entityClass .'::fromRow', $row);
+ }
+
+
+ /**
+ * Runs a sql query and returns an array of entities
+ * @param string $sql the prepare string
+ * @param array $params the params which should replace the ? in the sql query
+ * @param int $limit the maximum number of rows
+ * @param int $offset from which row we want to start
+ * @return array all fetched entities
+ * @since 7.0.0
+ */
+ protected function findEntities($sql, array $params=[], $limit=null, $offset=null) {
+ $stmt = $this->execute($sql, $params, $limit, $offset);
+
+ $entities = [];
+
+ while($row = $stmt->fetch()){
+ $entities[] = $this->mapRowToEntity($row);
+ }
+
+ $stmt->closeCursor();
+
+ return $entities;
+ }
+
+
+ /**
+ * Returns an db result and throws exceptions when there are more or less
+ * results
+ * @param string $sql the sql query
+ * @param array $params the parameters of the sql query
+ * @param int $limit the maximum number of rows
+ * @param int $offset from which row we want to start
+ * @throws DoesNotExistException if the item does not exist
+ * @throws MultipleObjectsReturnedException if more than one item exist
+ * @return Entity the entity
+ * @since 7.0.0
+ */
+ protected function findEntity($sql, array $params=[], $limit=null, $offset=null){
+ return $this->mapRowToEntity($this->findOneQuery($sql, $params, $limit, $offset));
+ }
+
+
+}
diff --git a/lib/public/AppFramework/Db/MultipleObjectsReturnedException.php b/lib/public/AppFramework/Db/MultipleObjectsReturnedException.php
new file mode 100644
index 00000000000..b9207051826
--- /dev/null
+++ b/lib/public/AppFramework/Db/MultipleObjectsReturnedException.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCP\AppFramework\Db;
+
+
+/**
+ * This is returned or should be returned when a find request finds more than one
+ * row
+ * @since 7.0.0
+ */
+class MultipleObjectsReturnedException extends \Exception {
+
+ /**
+ * Constructor
+ * @param string $msg the error message
+ * @since 7.0.0
+ */
+ public function __construct($msg){
+ parent::__construct($msg);
+ }
+
+}
diff --git a/lib/public/AppFramework/Http.php b/lib/public/AppFramework/Http.php
new file mode 100644
index 00000000000..e0108146db7
--- /dev/null
+++ b/lib/public/AppFramework/Http.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\HTTP class
+ */
+
+namespace OCP\AppFramework;
+
+/**
+ * Base class which contains constants for HTTP status codes
+ * @since 6.0.0
+ */
+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/ContentSecurityPolicy.php b/lib/public/AppFramework/Http/ContentSecurityPolicy.php
new file mode 100644
index 00000000000..7762ca809a2
--- /dev/null
+++ b/lib/public/AppFramework/Http/ContentSecurityPolicy.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author sualko <klaus@jsxc.org>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * Class ContentSecurityPolicy is a simple helper which allows applications to
+ * modify the Content-Security-Policy sent by ownCloud. Per default only JavaScript,
+ * stylesheets, images, fonts, media and connections from the same domain
+ * ('self') are allowed.
+ *
+ * Even if a value gets modified above defaults will still get appended. Please
+ * notice that ownCloud ships already with sensible defaults and those policies
+ * should require no modification at all for most use-cases.
+ *
+ * @package OCP\AppFramework\Http
+ * @since 8.1.0
+ */
+class ContentSecurityPolicy extends EmptyContentSecurityPolicy {
+ /** @var bool Whether inline JS snippets are allowed */
+ protected $inlineScriptAllowed = false;
+ /**
+ * @var bool Whether eval in JS scripts is allowed
+ * TODO: Disallow per default
+ * @link https://github.com/owncloud/core/issues/11925
+ */
+ protected $evalScriptAllowed = true;
+ /** @var array Domains from which scripts can get loaded */
+ protected $allowedScriptDomains = [
+ '\'self\'',
+ ];
+ /**
+ * @var bool Whether inline CSS is allowed
+ * TODO: Disallow per default
+ * @link https://github.com/owncloud/core/issues/13458
+ */
+ protected $inlineStyleAllowed = true;
+ /** @var array Domains from which CSS can get loaded */
+ protected $allowedStyleDomains = [
+ '\'self\'',
+ ];
+ /** @var array Domains from which images can get loaded */
+ protected $allowedImageDomains = [
+ '\'self\'',
+ 'data:',
+ 'blob:',
+ ];
+ /** @var array Domains to which connections can be done */
+ protected $allowedConnectDomains = [
+ '\'self\'',
+ ];
+ /** @var array Domains from which media elements can be loaded */
+ protected $allowedMediaDomains = [
+ '\'self\'',
+ ];
+ /** @var array Domains from which object elements can be loaded */
+ protected $allowedObjectDomains = [];
+ /** @var array Domains from which iframes can be loaded */
+ protected $allowedFrameDomains = [];
+ /** @var array Domains from which fonts can be loaded */
+ protected $allowedFontDomains = [
+ '\'self\'',
+ ];
+ /** @var array Domains from which web-workers and nested browsing content can load elements */
+ protected $allowedChildSrcDomains = [];
+}
diff --git a/lib/public/AppFramework/Http/DataDisplayResponse.php b/lib/public/AppFramework/Http/DataDisplayResponse.php
new file mode 100644
index 00000000000..4209c86a059
--- /dev/null
+++ b/lib/public/AppFramework/Http/DataDisplayResponse.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * Class DataDisplayResponse
+ *
+ * @package OCP\AppFramework\Http
+ * @since 8.1.0
+ */
+class DataDisplayResponse extends Response {
+
+ /**
+ * response data
+ * @var string;
+ */
+ protected $data;
+
+
+ /**
+ * @param string $data the data to display
+ * @param int $statusCode the Http status code, defaults to 200
+ * @param array $headers additional key value based headers
+ * @since 8.1.0
+ */
+ public function __construct($data="", $statusCode=Http::STATUS_OK,
+ $headers=[]) {
+ $this->data = $data;
+ $this->setStatus($statusCode);
+ $this->setHeaders(array_merge($this->getHeaders(), $headers));
+ $this->addHeader('Content-Disposition', 'inline; filename=""');
+ }
+
+ /**
+ * Outputs data. No processing is done.
+ * @return string
+ * @since 8.1.0
+ */
+ public function render() {
+ return $this->data;
+ }
+
+
+ /**
+ * Sets values in the data
+ * @param string $data the data to display
+ * @return DataDisplayResponse Reference to this object
+ * @since 8.1.0
+ */
+ public function setData($data){
+ $this->data = $data;
+
+ return $this;
+ }
+
+
+ /**
+ * Used to get the set parameters
+ * @return string the data
+ * @since 8.1.0
+ */
+ public function getData(){
+ return $this->data;
+ }
+
+}
diff --git a/lib/public/AppFramework/Http/DataDownloadResponse.php b/lib/public/AppFramework/Http/DataDownloadResponse.php
new file mode 100644
index 00000000000..55ef4e6c82c
--- /dev/null
+++ b/lib/public/AppFramework/Http/DataDownloadResponse.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * @author Georg Ehrke <georg@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCP\AppFramework\Http;
+
+/**
+ * Class DataDownloadResponse
+ *
+ * @package OCP\AppFramework\Http
+ * @since 8.0.0
+ */
+class DataDownloadResponse extends DownloadResponse {
+ /**
+ * @var string
+ */
+ private $data;
+
+ /**
+ * Creates a response that prompts the user to download the text
+ * @param string $data text to be downloaded
+ * @param string $filename the name that the downloaded file should have
+ * @param string $contentType the mimetype that the downloaded file should have
+ * @since 8.0.0
+ */
+ public function __construct($data, $filename, $contentType) {
+ $this->data = $data;
+ parent::__construct($filename, $contentType);
+ }
+
+ /**
+ * @param string $data
+ * @since 8.0.0
+ */
+ public function setData($data) {
+ $this->data = $data;
+ }
+
+ /**
+ * @return string
+ * @since 8.0.0
+ */
+ public function render() {
+ return $this->data;
+ }
+}
diff --git a/lib/public/AppFramework/Http/DataResponse.php b/lib/public/AppFramework/Http/DataResponse.php
new file mode 100644
index 00000000000..3ec4e2bdc32
--- /dev/null
+++ b/lib/public/AppFramework/Http/DataResponse.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\HTTP\DataResponse class
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * A generic DataResponse class that is used to return generic data responses
+ * for responders to transform
+ * @since 8.0.0
+ */
+class DataResponse extends Response {
+
+ /**
+ * response data
+ * @var array|object
+ */
+ protected $data;
+
+
+ /**
+ * @param array|object $data the object or array that should be transformed
+ * @param int $statusCode the Http status code, defaults to 200
+ * @param array $headers additional key value based headers
+ * @since 8.0.0
+ */
+ public function __construct($data=array(), $statusCode=Http::STATUS_OK,
+ array $headers=array()) {
+ $this->data = $data;
+ $this->setStatus($statusCode);
+ $this->setHeaders(array_merge($this->getHeaders(), $headers));
+ }
+
+
+ /**
+ * Sets values in the data json array
+ * @param array|object $data an array or object which will be transformed
+ * @return DataResponse Reference to this object
+ * @since 8.0.0
+ */
+ public function setData($data){
+ $this->data = $data;
+
+ return $this;
+ }
+
+
+ /**
+ * Used to get the set parameters
+ * @return array the data
+ * @since 8.0.0
+ */
+ public function getData(){
+ return $this->data;
+ }
+
+
+}
diff --git a/lib/public/AppFramework/Http/DownloadResponse.php b/lib/public/AppFramework/Http/DownloadResponse.php
new file mode 100644
index 00000000000..af0d76951ca
--- /dev/null
+++ b/lib/public/AppFramework/Http/DownloadResponse.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCP\AppFramework\Http;
+
+
+/**
+ * Prompts the user to download the a file
+ * @since 7.0.0
+ */
+class DownloadResponse extends \OCP\AppFramework\Http\Response {
+
+ private $filename;
+ private $contentType;
+
+ /**
+ * Creates a response that prompts the user to download the file
+ * @param string $filename the name that the downloaded file should have
+ * @param string $contentType the mimetype that the downloaded file should have
+ * @since 7.0.0
+ */
+ public function __construct($filename, $contentType) {
+ $this->filename = $filename;
+ $this->contentType = $contentType;
+
+ $this->addHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
+ $this->addHeader('Content-Type', $contentType);
+ }
+
+
+}
diff --git a/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php b/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php
new file mode 100644
index 00000000000..61718ff7c0e
--- /dev/null
+++ b/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php
@@ -0,0 +1,385 @@
+<?php
+/**
+ * @author Lukas Reschke <lukas@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * Class EmptyContentSecurityPolicy is a simple helper which allows applications
+ * to modify the Content-Security-Policy sent by ownCloud. Per default the policy
+ * is forbidding everything.
+ *
+ * As alternative with sane exemptions look at ContentSecurityPolicy
+ *
+ * @see \OCP\AppFramework\Http\ContentSecurityPolicy
+ * @package OCP\AppFramework\Http
+ * @since 9.0.0
+ */
+class EmptyContentSecurityPolicy {
+ /** @var bool Whether inline JS snippets are allowed */
+ protected $inlineScriptAllowed = null;
+ /**
+ * @var bool Whether eval in JS scripts is allowed
+ * TODO: Disallow per default
+ * @link https://github.com/owncloud/core/issues/11925
+ */
+ protected $evalScriptAllowed = null;
+ /** @var array Domains from which scripts can get loaded */
+ protected $allowedScriptDomains = null;
+ /**
+ * @var bool Whether inline CSS is allowed
+ * TODO: Disallow per default
+ * @link https://github.com/owncloud/core/issues/13458
+ */
+ protected $inlineStyleAllowed = null;
+ /** @var array Domains from which CSS can get loaded */
+ protected $allowedStyleDomains = null;
+ /** @var array Domains from which images can get loaded */
+ protected $allowedImageDomains = null;
+ /** @var array Domains to which connections can be done */
+ protected $allowedConnectDomains = null;
+ /** @var array Domains from which media elements can be loaded */
+ protected $allowedMediaDomains = null;
+ /** @var array Domains from which object elements can be loaded */
+ protected $allowedObjectDomains = null;
+ /** @var array Domains from which iframes can be loaded */
+ protected $allowedFrameDomains = null;
+ /** @var array Domains from which fonts can be loaded */
+ protected $allowedFontDomains = null;
+ /** @var array Domains from which web-workers and nested browsing content can load elements */
+ protected $allowedChildSrcDomains = null;
+
+ /**
+ * Whether inline JavaScript snippets are allowed or forbidden
+ * @param bool $state
+ * @return $this
+ * @since 8.1.0
+ */
+ public function allowInlineScript($state = false) {
+ $this->inlineScriptAllowed = $state;
+ return $this;
+ }
+
+ /**
+ * Whether eval in JavaScript is allowed or forbidden
+ * @param bool $state
+ * @return $this
+ * @since 8.1.0
+ */
+ public function allowEvalScript($state = true) {
+ $this->evalScriptAllowed = $state;
+ return $this;
+ }
+
+ /**
+ * Allows to execute JavaScript files from a specific domain. Use * to
+ * allow JavaScript from all domains.
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedScriptDomain($domain) {
+ $this->allowedScriptDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed script domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowScriptDomain($domain) {
+ $this->allowedScriptDomains = array_diff($this->allowedScriptDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * Whether inline CSS snippets are allowed or forbidden
+ * @param bool $state
+ * @return $this
+ * @since 8.1.0
+ */
+ public function allowInlineStyle($state = true) {
+ $this->inlineStyleAllowed = $state;
+ return $this;
+ }
+
+ /**
+ * Allows to execute CSS files from a specific domain. Use * to allow
+ * CSS from all domains.
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedStyleDomain($domain) {
+ $this->allowedStyleDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed style domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowStyleDomain($domain) {
+ $this->allowedStyleDomains = array_diff($this->allowedStyleDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * Allows using fonts from a specific domain. Use * to allow
+ * fonts from all domains.
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedFontDomain($domain) {
+ $this->allowedFontDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed font domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowFontDomain($domain) {
+ $this->allowedFontDomains = array_diff($this->allowedFontDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * Allows embedding images from a specific domain. Use * to allow
+ * images from all domains.
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedImageDomain($domain) {
+ $this->allowedImageDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed image domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowImageDomain($domain) {
+ $this->allowedImageDomains = array_diff($this->allowedImageDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * To which remote domains the JS connect to.
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedConnectDomain($domain) {
+ $this->allowedConnectDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed connect domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowConnectDomain($domain) {
+ $this->allowedConnectDomains = array_diff($this->allowedConnectDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * From which domains media elements can be embedded.
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedMediaDomain($domain) {
+ $this->allowedMediaDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed media domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowMediaDomain($domain) {
+ $this->allowedMediaDomains = array_diff($this->allowedMediaDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * From which domains objects such as <object>, <embed> or <applet> are executed
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedObjectDomain($domain) {
+ $this->allowedObjectDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed object domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowObjectDomain($domain) {
+ $this->allowedObjectDomains = array_diff($this->allowedObjectDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * Which domains can be embedded in an iframe
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedFrameDomain($domain) {
+ $this->allowedFrameDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed frame domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowFrameDomain($domain) {
+ $this->allowedFrameDomains = array_diff($this->allowedFrameDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * Domains from which web-workers and nested browsing content can load elements
+ * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
+ * @return $this
+ * @since 8.1.0
+ */
+ public function addAllowedChildSrcDomain($domain) {
+ $this->allowedChildSrcDomains[] = $domain;
+ return $this;
+ }
+
+ /**
+ * Remove the specified allowed child src domain from the allowed domains.
+ *
+ * @param string $domain
+ * @return $this
+ * @since 8.1.0
+ */
+ public function disallowChildSrcDomain($domain) {
+ $this->allowedChildSrcDomains = array_diff($this->allowedChildSrcDomains, [$domain]);
+ return $this;
+ }
+
+ /**
+ * Get the generated Content-Security-Policy as a string
+ * @return string
+ * @since 8.1.0
+ */
+ public function buildPolicy() {
+ $policy = "default-src 'none';";
+
+ if(!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
+ $policy .= 'script-src ';
+ if(is_array($this->allowedScriptDomains)) {
+ $policy .= implode(' ', $this->allowedScriptDomains);
+ }
+ if($this->inlineScriptAllowed) {
+ $policy .= ' \'unsafe-inline\'';
+ }
+ if($this->evalScriptAllowed) {
+ $policy .= ' \'unsafe-eval\'';
+ }
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedStyleDomains) || $this->inlineStyleAllowed) {
+ $policy .= 'style-src ';
+ if(is_array($this->allowedStyleDomains)) {
+ $policy .= implode(' ', $this->allowedStyleDomains);
+ }
+ if($this->inlineStyleAllowed) {
+ $policy .= ' \'unsafe-inline\'';
+ }
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedImageDomains)) {
+ $policy .= 'img-src ' . implode(' ', $this->allowedImageDomains);
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedFontDomains)) {
+ $policy .= 'font-src ' . implode(' ', $this->allowedFontDomains);
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedConnectDomains)) {
+ $policy .= 'connect-src ' . implode(' ', $this->allowedConnectDomains);
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedMediaDomains)) {
+ $policy .= 'media-src ' . implode(' ', $this->allowedMediaDomains);
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedObjectDomains)) {
+ $policy .= 'object-src ' . implode(' ', $this->allowedObjectDomains);
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedFrameDomains)) {
+ $policy .= 'frame-src ' . implode(' ', $this->allowedFrameDomains);
+ $policy .= ';';
+ }
+
+ if(!empty($this->allowedChildSrcDomains)) {
+ $policy .= 'child-src ' . implode(' ', $this->allowedChildSrcDomains);
+ $policy .= ';';
+ }
+
+ return rtrim($policy, ';');
+ }
+}
diff --git a/lib/public/AppFramework/Http/ICallbackResponse.php b/lib/public/AppFramework/Http/ICallbackResponse.php
new file mode 100644
index 00000000000..97de484e917
--- /dev/null
+++ b/lib/public/AppFramework/Http/ICallbackResponse.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Http;
+
+
+/**
+ * Interface ICallbackResponse
+ *
+ * @package OCP\AppFramework\Http
+ * @since 8.1.0
+ */
+interface ICallbackResponse {
+
+ /**
+ * Outputs the content that should be printed
+ *
+ * @param IOutput $output a small wrapper that handles output
+ * @since 8.1.0
+ */
+ function callback(IOutput $output);
+
+}
diff --git a/lib/public/AppFramework/Http/IOutput.php b/lib/public/AppFramework/Http/IOutput.php
new file mode 100644
index 00000000000..6c404c0b026
--- /dev/null
+++ b/lib/public/AppFramework/Http/IOutput.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Http;
+
+
+/**
+ * Very thin wrapper class to make output testable
+ * @since 8.1.0
+ */
+interface IOutput {
+
+ /**
+ * @param string $out
+ * @since 8.1.0
+ */
+ public function setOutput($out);
+
+ /**
+ * @param string $path
+ *
+ * @return bool false if an error occurred
+ * @since 8.1.0
+ */
+ public function setReadfile($path);
+
+ /**
+ * @param string $header
+ * @since 8.1.0
+ */
+ public function setHeader($header);
+
+ /**
+ * @return int returns the current http response code
+ * @since 8.1.0
+ */
+ public function getHttpResponseCode();
+
+ /**
+ * @param int $code sets the http status code
+ * @since 8.1.0
+ */
+ public function setHttpResponseCode($code);
+
+ /**
+ * @param string $name
+ * @param string $value
+ * @param int $expire
+ * @param string $path
+ * @param string $domain
+ * @param bool $secure
+ * @param bool $httpOnly
+ * @since 8.1.0
+ */
+ public function setCookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
+
+}
diff --git a/lib/public/AppFramework/Http/JSONResponse.php b/lib/public/AppFramework/Http/JSONResponse.php
new file mode 100644
index 00000000000..89433fd23e5
--- /dev/null
+++ b/lib/public/AppFramework/Http/JSONResponse.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\HTTP\JSONResponse class
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * A renderer for JSON calls
+ * @since 6.0.0
+ */
+class JSONResponse extends Response {
+
+ /**
+ * response data
+ * @var array|object
+ */
+ protected $data;
+
+
+ /**
+ * constructor of JSONResponse
+ * @param array|object $data the object or array that should be transformed
+ * @param int $statusCode the Http status code, defaults to 200
+ * @since 6.0.0
+ */
+ public function __construct($data=array(), $statusCode=Http::STATUS_OK) {
+ $this->data = $data;
+ $this->setStatus($statusCode);
+ $this->addHeader('Content-Type', 'application/json; charset=utf-8');
+ }
+
+
+ /**
+ * Returns the rendered json
+ * @return string the rendered json
+ * @since 6.0.0
+ * @throws \Exception If data could not get encoded
+ */
+ public function render() {
+ $response = json_encode($this->data, JSON_HEX_TAG);
+ if($response === false) {
+ throw new \Exception(sprintf('Could not json_encode due to invalid ' .
+ 'non UTF-8 characters in the array: %s', var_export($this->data, true)));
+ }
+
+ return $response;
+ }
+
+ /**
+ * Sets values in the data json array
+ * @param array|object $data an array or object which will be transformed
+ * to JSON
+ * @return JSONResponse Reference to this object
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function setData($data){
+ $this->data = $data;
+
+ return $this;
+ }
+
+
+ /**
+ * Used to get the set parameters
+ * @return array the data
+ * @since 6.0.0
+ */
+ public function getData(){
+ return $this->data;
+ }
+
+}
diff --git a/lib/public/AppFramework/Http/NotFoundResponse.php b/lib/public/AppFramework/Http/NotFoundResponse.php
new file mode 100644
index 00000000000..8dcebd7cceb
--- /dev/null
+++ b/lib/public/AppFramework/Http/NotFoundResponse.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+use OCP\Template;
+
+/**
+ * A generic 404 response showing an 404 error page as well to the end-user
+ * @since 8.1.0
+ */
+class NotFoundResponse extends Response {
+
+ /**
+ * @since 8.1.0
+ */
+ public function __construct() {
+ $this->setStatus(404);
+ }
+
+ /**
+ * @return string
+ * @since 8.1.0
+ */
+ public function render() {
+ $template = new Template('core', '404', 'guest');
+ return $template->fetchPage();
+ }
+}
diff --git a/lib/public/AppFramework/Http/OCSResponse.php b/lib/public/AppFramework/Http/OCSResponse.php
new file mode 100644
index 00000000000..da9de712c0a
--- /dev/null
+++ b/lib/public/AppFramework/Http/OCSResponse.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\HTTP\JSONResponse class
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * A renderer for OCS responses
+ * @since 8.1.0
+ */
+class OCSResponse extends Response {
+
+ private $data;
+ private $format;
+ private $statuscode;
+ private $message;
+ private $itemscount;
+ private $itemsperpage;
+
+ /**
+ * generates the xml or json response for the API call from an multidimenional data array.
+ * @param string $format
+ * @param int $statuscode
+ * @param string $message
+ * @param array $data
+ * @param int|string $itemscount
+ * @param int|string $itemsperpage
+ * @since 8.1.0
+ */
+ public function __construct($format, $statuscode, $message,
+ $data=[], $itemscount='',
+ $itemsperpage='') {
+ $this->format = $format;
+ $this->statuscode = $statuscode;
+ $this->message = $message;
+ $this->data = $data;
+ $this->itemscount = $itemscount;
+ $this->itemsperpage = $itemsperpage;
+
+ // set the correct header based on the format parameter
+ if ($format === 'json') {
+ $this->addHeader(
+ 'Content-Type', 'application/json; charset=utf-8'
+ );
+ } else {
+ $this->addHeader(
+ 'Content-Type', 'application/xml; charset=utf-8'
+ );
+ }
+ }
+
+ /**
+ * @return string
+ * @since 8.1.0
+ */
+ public function render() {
+ $r = new \OC_OCS_Result($this->data, $this->statuscode, $this->message);
+ $r->setTotalItems($this->itemscount);
+ $r->setItemsPerPage($this->itemsperpage);
+
+ return \OC_API::renderResult($this->format, $r->getMeta(), $r->getData());
+ }
+
+
+}
diff --git a/lib/public/AppFramework/Http/RedirectResponse.php b/lib/public/AppFramework/Http/RedirectResponse.php
new file mode 100644
index 00000000000..97140c9955f
--- /dev/null
+++ b/lib/public/AppFramework/Http/RedirectResponse.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author v1r0x <vinzenz.rosenkranz@gmail.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http;
+
+
+/**
+ * Redirects to a different URL
+ * @since 7.0.0
+ */
+class RedirectResponse extends Response {
+
+ private $redirectURL;
+
+ /**
+ * Creates a response that redirects to a url
+ * @param string $redirectURL the url to redirect to
+ * @since 7.0.0
+ */
+ public function __construct($redirectURL) {
+ $this->redirectURL = $redirectURL;
+ $this->setStatus(Http::STATUS_SEE_OTHER);
+ $this->addHeader('Location', $redirectURL);
+ }
+
+
+ /**
+ * @return string the url to redirect
+ * @since 7.0.0
+ */
+ public function getRedirectURL() {
+ return $this->redirectURL;
+ }
+
+
+}
diff --git a/lib/public/AppFramework/Http/Response.php b/lib/public/AppFramework/Http/Response.php
new file mode 100644
index 00000000000..253d58b86ff
--- /dev/null
+++ b/lib/public/AppFramework/Http/Response.php
@@ -0,0 +1,326 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\HTTP\Response class
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * Base class for responses. Also used to just send headers.
+ *
+ * It handles headers, HTTP status code, last modified and ETag.
+ * @since 6.0.0
+ */
+class Response {
+
+ /**
+ * Headers - defaults to ['Cache-Control' => 'no-cache, must-revalidate']
+ * @var array
+ */
+ private $headers = array(
+ 'Cache-Control' => 'no-cache, must-revalidate'
+ );
+
+
+ /**
+ * Cookies that will be need to be constructed as header
+ * @var array
+ */
+ private $cookies = array();
+
+
+ /**
+ * HTTP status code - defaults to STATUS OK
+ * @var int
+ */
+ private $status = Http::STATUS_OK;
+
+
+ /**
+ * Last modified date
+ * @var \DateTime
+ */
+ private $lastModified;
+
+
+ /**
+ * ETag
+ * @var string
+ */
+ private $ETag;
+
+ /** @var ContentSecurityPolicy|null Used Content-Security-Policy */
+ private $contentSecurityPolicy = null;
+
+
+ /**
+ * Caches the response
+ * @param int $cacheSeconds the amount of seconds that should be cached
+ * if 0 then caching will be disabled
+ * @return $this
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function cacheFor($cacheSeconds) {
+
+ if($cacheSeconds > 0) {
+ $this->addHeader('Cache-Control', 'max-age=' . $cacheSeconds .
+ ', must-revalidate');
+ } else {
+ $this->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds a new cookie to the response
+ * @param string $name The name of the cookie
+ * @param string $value The value of the cookie
+ * @param \DateTime|null $expireDate Date on that the cookie should expire, if set
+ * to null cookie will be considered as session
+ * cookie.
+ * @return $this
+ * @since 8.0.0
+ */
+ public function addCookie($name, $value, \DateTime $expireDate = null) {
+ $this->cookies[$name] = array('value' => $value, 'expireDate' => $expireDate);
+ return $this;
+ }
+
+
+ /**
+ * Set the specified cookies
+ * @param array $cookies array('foo' => array('value' => 'bar', 'expire' => null))
+ * @return $this
+ * @since 8.0.0
+ */
+ public function setCookies(array $cookies) {
+ $this->cookies = $cookies;
+ return $this;
+ }
+
+
+ /**
+ * Invalidates the specified cookie
+ * @param string $name
+ * @return $this
+ * @since 8.0.0
+ */
+ public function invalidateCookie($name) {
+ $this->addCookie($name, 'expired', new \DateTime('1971-01-01 00:00'));
+ return $this;
+ }
+
+ /**
+ * Invalidates the specified cookies
+ * @param array $cookieNames array('foo', 'bar')
+ * @return $this
+ * @since 8.0.0
+ */
+ public function invalidateCookies(array $cookieNames) {
+ foreach($cookieNames as $cookieName) {
+ $this->invalidateCookie($cookieName);
+ }
+ return $this;
+ }
+
+ /**
+ * Returns the cookies
+ * @return array
+ * @since 8.0.0
+ */
+ public function getCookies() {
+ return $this->cookies;
+ }
+
+ /**
+ * 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
+ * @return $this
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function addHeader($name, $value) {
+ $name = trim($name); // always remove leading and trailing whitespace
+ // to be able to reliably check for security
+ // headers
+
+ if(is_null($value)) {
+ unset($this->headers[$name]);
+ } else {
+ $this->headers[$name] = $value;
+ }
+
+ return $this;
+ }
+
+
+ /**
+ * Set the headers
+ * @param array $headers value header pairs
+ * @return $this
+ * @since 8.0.0
+ */
+ public function setHeaders(array $headers) {
+ $this->headers = $headers;
+
+ return $this;
+ }
+
+
+ /**
+ * Returns the set headers
+ * @return array the headers
+ * @since 6.0.0
+ */
+ public function getHeaders() {
+ $mergeWith = [];
+
+ if($this->lastModified) {
+ $mergeWith['Last-Modified'] =
+ $this->lastModified->format(\DateTime::RFC2822);
+ }
+
+ // Build Content-Security-Policy and use default if none has been specified
+ if(is_null($this->contentSecurityPolicy)) {
+ $this->setContentSecurityPolicy(new ContentSecurityPolicy());
+ }
+ $this->headers['Content-Security-Policy'] = $this->contentSecurityPolicy->buildPolicy();
+
+ if($this->ETag) {
+ $mergeWith['ETag'] = '"' . $this->ETag . '"';
+ }
+
+ return array_merge($mergeWith, $this->headers);
+ }
+
+
+ /**
+ * By default renders no output
+ * @return null
+ * @since 6.0.0
+ */
+ public function render() {
+ return null;
+ }
+
+
+ /**
+ * Set response status
+ * @param int $status a HTTP status code, see also the STATUS constants
+ * @return Response Reference to this object
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function setStatus($status) {
+ $this->status = $status;
+
+ return $this;
+ }
+
+ /**
+ * Set a Content-Security-Policy
+ * @param ContentSecurityPolicy $csp Policy to set for the response object
+ * @return $this
+ * @since 8.1.0
+ */
+ public function setContentSecurityPolicy(ContentSecurityPolicy $csp) {
+ $this->contentSecurityPolicy = $csp;
+ return $this;
+ }
+
+ /**
+ * Get the currently used Content-Security-Policy
+ * @return ContentSecurityPolicy|null Used Content-Security-Policy or null if
+ * none specified.
+ * @since 8.1.0
+ */
+ public function getContentSecurityPolicy() {
+ return $this->contentSecurityPolicy;
+ }
+
+
+ /**
+ * Get response status
+ * @since 6.0.0
+ */
+ public function getStatus() {
+ return $this->status;
+ }
+
+
+ /**
+ * Get the ETag
+ * @return string the etag
+ * @since 6.0.0
+ */
+ public function getETag() {
+ return $this->ETag;
+ }
+
+
+ /**
+ * Get "last modified" date
+ * @return \DateTime RFC2822 formatted last modified date
+ * @since 6.0.0
+ */
+ public function getLastModified() {
+ return $this->lastModified;
+ }
+
+
+ /**
+ * Set the ETag
+ * @param string $ETag
+ * @return Response Reference to this object
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function setETag($ETag) {
+ $this->ETag = $ETag;
+
+ return $this;
+ }
+
+
+ /**
+ * Set "last modified" date
+ * @param \DateTime $lastModified
+ * @return Response Reference to this object
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function setLastModified($lastModified) {
+ $this->lastModified = $lastModified;
+
+ return $this;
+ }
+
+
+}
diff --git a/lib/public/AppFramework/Http/StreamResponse.php b/lib/public/AppFramework/Http/StreamResponse.php
new file mode 100644
index 00000000000..e9157f9ddb2
--- /dev/null
+++ b/lib/public/AppFramework/Http/StreamResponse.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Http;
+
+use OCP\AppFramework\Http;
+
+/**
+ * Class StreamResponse
+ *
+ * @package OCP\AppFramework\Http
+ * @since 8.1.0
+ */
+class StreamResponse extends Response implements ICallbackResponse {
+ /** @var string */
+ private $filePath;
+
+ /**
+ * @param string $filePath the path to the file which should be streamed
+ * @since 8.1.0
+ */
+ public function __construct ($filePath) {
+ $this->filePath = $filePath;
+ }
+
+
+ /**
+ * Streams the file using readfile
+ *
+ * @param IOutput $output a small wrapper that handles output
+ * @since 8.1.0
+ */
+ public function callback (IOutput $output) {
+ // handle caching
+ if ($output->getHttpResponseCode() !== Http::STATUS_NOT_MODIFIED) {
+ if (!file_exists($this->filePath)) {
+ $output->setHttpResponseCode(Http::STATUS_NOT_FOUND);
+ } elseif ($output->setReadfile($this->filePath) === false) {
+ $output->setHttpResponseCode(Http::STATUS_BAD_REQUEST);
+ }
+ }
+ }
+
+}
diff --git a/lib/public/AppFramework/Http/TemplateResponse.php b/lib/public/AppFramework/Http/TemplateResponse.php
new file mode 100644
index 00000000000..7774d881e4d
--- /dev/null
+++ b/lib/public/AppFramework/Http/TemplateResponse.php
@@ -0,0 +1,159 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\HTTP\TemplateResponse class
+ */
+
+namespace OCP\AppFramework\Http;
+
+
+/**
+ * Response for a normal template
+ * @since 6.0.0
+ */
+class TemplateResponse extends Response {
+
+ /**
+ * name of the template
+ * @var string
+ */
+ protected $templateName;
+
+ /**
+ * parameters
+ * @var array
+ */
+ protected $params;
+
+ /**
+ * rendering type (admin, user, blank)
+ * @var string
+ */
+ protected $renderAs;
+
+ /**
+ * app name
+ * @var string
+ */
+ protected $appName;
+
+ /**
+ * 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
+ * @since 6.0.0 - parameters $params and $renderAs were added in 7.0.0
+ */
+ public function __construct($appName, $templateName, array $params=array(),
+ $renderAs='user') {
+ $this->templateName = $templateName;
+ $this->appName = $appName;
+ $this->params = $params;
+ $this->renderAs = $renderAs;
+ }
+
+
+ /**
+ * Sets template parameters
+ * @param array $params an array with key => value structure which sets template
+ * variables
+ * @return TemplateResponse Reference to this object
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function setParams(array $params){
+ $this->params = $params;
+
+ return $this;
+ }
+
+
+ /**
+ * Used for accessing the set parameters
+ * @return array the params
+ * @since 6.0.0
+ */
+ public function getParams(){
+ return $this->params;
+ }
+
+
+ /**
+ * Used for accessing the name of the set template
+ * @return string the name of the used template
+ * @since 6.0.0
+ */
+ 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
+ * @return TemplateResponse Reference to this object
+ * @since 6.0.0 - return value was added in 7.0.0
+ */
+ public function renderAs($renderAs){
+ $this->renderAs = $renderAs;
+
+ return $this;
+ }
+
+
+ /**
+ * Returns the set renderAs
+ * @return string the renderAs value
+ * @since 6.0.0
+ */
+ public function getRenderAs(){
+ return $this->renderAs;
+ }
+
+
+ /**
+ * Returns the rendered html
+ * @return string the rendered html
+ * @since 6.0.0
+ */
+ public function render(){
+ // \OCP\Template needs an empty string instead of 'blank' for an unwrapped response
+ $renderAs = $this->renderAs === 'blank' ? '' : $this->renderAs;
+
+ $template = new \OCP\Template($this->appName, $this->templateName, $renderAs);
+
+ foreach($this->params as $key => $value){
+ $template->assign($key, $value);
+ }
+
+ return $template->fetchPage();
+ }
+
+}
diff --git a/lib/public/AppFramework/IApi.php b/lib/public/AppFramework/IApi.php
new file mode 100644
index 00000000000..66614328873
--- /dev/null
+++ b/lib/public/AppFramework/IApi.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework/IApi interface
+ */
+
+namespace OCP\AppFramework;
+
+
+/**
+ * A few very basic and frequently used API functions are combined in here
+ * @deprecated 8.0.0
+ */
+interface IApi {
+
+
+ /**
+ * Gets the userid of the current user
+ * @return string the user id of the current user
+ * @deprecated 8.0.0 Use \OC::$server->getUserSession()->getUser()->getUID()
+ */
+ function getUserId();
+
+
+ /**
+ * Adds a new javascript file
+ * @deprecated 8.0.0 include javascript and css in template files
+ * @param string $scriptName the name of the javascript in js/ without the suffix
+ * @param string $appName the name of the app, defaults to the current one
+ * @return void
+ */
+ function addScript($scriptName, $appName = null);
+
+
+ /**
+ * Adds a new css file
+ * @deprecated 8.0.0 include javascript and css in template files
+ * @param string $styleName the name of the css file in css/without the suffix
+ * @param string $appName the name of the app, defaults to the current one
+ * @return void
+ */
+ function addStyle($styleName, $appName = null);
+
+
+ /**
+ * @deprecated 8.0.0 include javascript and css in template files
+ * shorthand for addScript for files in the 3rdparty directory
+ * @param string $name the name of the file without the suffix
+ * @return void
+ */
+ function add3rdPartyScript($name);
+
+
+ /**
+ * @deprecated 8.0.0 include javascript and css in template files
+ * shorthand for addStyle for files in the 3rdparty directory
+ * @param string $name the name of the file without the suffix
+ * @return void
+ */
+ function add3rdPartyStyle($name);
+
+
+ /**
+ * Checks if an app is enabled
+ * @deprecated 8.0.0 communication between apps should happen over built in
+ * callbacks or interfaces (check the contacts and calendar managers)
+ * Checks if an app is enabled
+ * also use \OC::$server->getAppManager()->isEnabledForUser($appName)
+ * @param string $appName the name of an app
+ * @return bool true if app is enabled
+ */
+ public function isAppEnabled($appName);
+
+}
diff --git a/lib/public/AppFramework/IAppContainer.php b/lib/public/AppFramework/IAppContainer.php
new file mode 100644
index 00000000000..905539e735e
--- /dev/null
+++ b/lib/public/AppFramework/IAppContainer.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework;
+
+use OCP\AppFramework\IApi;
+use OCP\IContainer;
+
+/**
+ * Class IAppContainer
+ * @package OCP\AppFramework
+ *
+ * This container interface provides short cuts for app developers to access predefined app service.
+ * @since 6.0.0
+ */
+interface IAppContainer extends IContainer {
+
+ /**
+ * used to return the appname of the set application
+ * @return string the name of your application
+ * @since 6.0.0
+ */
+ function getAppName();
+
+ /**
+ * @deprecated 8.0.0 implements only deprecated methods
+ * @return IApi
+ * @since 6.0.0
+ */
+ function getCoreApi();
+
+ /**
+ * @return \OCP\IServerContainer
+ * @since 6.0.0
+ */
+ function getServer();
+
+ /**
+ * @param string $middleWare
+ * @return boolean
+ * @since 6.0.0
+ */
+ function registerMiddleWare($middleWare);
+
+ /**
+ * @deprecated 8.0.0 use IUserSession->isLoggedIn()
+ * @return boolean
+ * @since 6.0.0
+ */
+ function isLoggedIn();
+
+ /**
+ * @deprecated 8.0.0 use IGroupManager->isAdmin($userId)
+ * @return boolean
+ * @since 6.0.0
+ */
+ function isAdminUser();
+
+ /**
+ * @deprecated 8.0.0 use the ILogger instead
+ * @param string $message
+ * @param string $level
+ * @return mixed
+ * @since 6.0.0
+ */
+ function log($message, $level);
+
+ /**
+ * Register a capability
+ *
+ * @param string $serviceName e.g. 'OCA\Files\Capabilities'
+ * @since 8.2.0
+ */
+ public function registerCapability($serviceName);
+}
diff --git a/lib/public/AppFramework/Middleware.php b/lib/public/AppFramework/Middleware.php
new file mode 100644
index 00000000000..12ec5f7d573
--- /dev/null
+++ b/lib/public/AppFramework/Middleware.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Thomas Tanghus <thomas@tanghus.net>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\Middleware class
+ */
+
+namespace OCP\AppFramework;
+
+use OCP\AppFramework\Controller;
+use OCP\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/
+ * @since 6.0.0
+ */
+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
+ * @since 6.0.0
+ */
+ 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 can't handle it
+ * @return Response a Response object in case that the exception was handled
+ * @since 6.0.0
+ */
+ 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
+ * @since 6.0.0
+ */
+ 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
+ * @since 6.0.0
+ */
+ public function beforeOutput($controller, $methodName, $output){
+ return $output;
+ }
+
+}
diff --git a/lib/public/AppFramework/OCSController.php b/lib/public/AppFramework/OCSController.php
new file mode 100644
index 00000000000..4736e94326e
--- /dev/null
+++ b/lib/public/AppFramework/OCSController.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * AppFramework\Controller class
+ */
+
+namespace OCP\AppFramework;
+
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\OCSResponse;
+use OCP\IRequest;
+
+
+/**
+ * Base class to inherit your controllers from that are used for RESTful APIs
+ * @since 8.1.0
+ */
+abstract class OCSController extends ApiController {
+
+ /**
+ * constructor of the controller
+ * @param string $appName the name of the app
+ * @param IRequest $request an instance of the request
+ * @param string $corsMethods comma separated string of HTTP verbs which
+ * should be allowed for websites or webapps when calling your API, defaults to
+ * 'PUT, POST, GET, DELETE, PATCH'
+ * @param string $corsAllowedHeaders comma separated string of HTTP headers
+ * which should be allowed for websites or webapps when calling your API,
+ * defaults to 'Authorization, Content-Type, Accept'
+ * @param int $corsMaxAge number in seconds how long a preflighted OPTIONS
+ * request should be cached, defaults to 1728000 seconds
+ * @since 8.1.0
+ */
+ public function __construct($appName,
+ IRequest $request,
+ $corsMethods='PUT, POST, GET, DELETE, PATCH',
+ $corsAllowedHeaders='Authorization, Content-Type, Accept',
+ $corsMaxAge=1728000){
+ parent::__construct($appName, $request, $corsMethods,
+ $corsAllowedHeaders, $corsMaxAge);
+ $this->registerResponder('json', function ($data) {
+ return $this->buildOCSResponse('json', $data);
+ });
+ $this->registerResponder('xml', function ($data) {
+ return $this->buildOCSResponse('xml', $data);
+ });
+ }
+
+
+ /**
+ * Unwrap data and build ocs response
+ * @param string $format json or xml
+ * @param array|DataResponse $data the data which should be transformed
+ * @since 8.1.0
+ */
+ private function buildOCSResponse($format, $data) {
+ if ($data instanceof DataResponse) {
+ $data = $data->getData();
+ }
+
+ $params = [
+ 'statuscode' => 100,
+ 'message' => 'OK',
+ 'data' => [],
+ 'itemscount' => '',
+ 'itemsperpage' => ''
+ ];
+
+ foreach ($data as $key => $value) {
+ $params[$key] = $value;
+ }
+
+ return new OCSResponse(
+ $format, $params['statuscode'],
+ $params['message'], $params['data'],
+ $params['itemscount'], $params['itemsperpage']
+ );
+ }
+
+}
diff --git a/lib/public/AppFramework/QueryException.php b/lib/public/AppFramework/QueryException.php
new file mode 100644
index 00000000000..62ab77dd839
--- /dev/null
+++ b/lib/public/AppFramework/QueryException.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework;
+
+use Exception;
+
+/**
+ * Class QueryException
+ *
+ * @package OCP\AppFramework
+ * @since 8.1.0
+ */
+class QueryException extends Exception {}
diff --git a/lib/public/AppFramework/Utility/IControllerMethodReflector.php b/lib/public/AppFramework/Utility/IControllerMethodReflector.php
new file mode 100644
index 00000000000..e2939ff8896
--- /dev/null
+++ b/lib/public/AppFramework/Utility/IControllerMethodReflector.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Olivier Paroz <github@oparoz.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\AppFramework\Utility;
+
+/**
+ * Interface ControllerMethodReflector
+ *
+ * Reads and parses annotations from doc comments
+ *
+ * @package OCP\AppFramework\Utility
+ * @since 8.0.0
+ */
+interface IControllerMethodReflector {
+
+ /**
+ * @param object $object an object or classname
+ * @param string $method the method which we want to inspect
+ * @return void
+ * @since 8.0.0
+ */
+ public function reflect($object, $method);
+
+ /**
+ * 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
+ * @since 8.0.0
+ */
+ public function getType($parameter);
+
+ /**
+ * @return array the arguments of the method with key => default value
+ * @since 8.0.0
+ */
+ public function getParameters();
+
+ /**
+ * Check if a method contains an annotation
+ *
+ * @param string $name the name of the annotation
+ * @return bool true if the annotation is found
+ * @since 8.0.0
+ */
+ public function hasAnnotation($name);
+
+}
diff --git a/lib/public/AppFramework/Utility/ITimeFactory.php b/lib/public/AppFramework/Utility/ITimeFactory.php
new file mode 100644
index 00000000000..a3333dd1949
--- /dev/null
+++ b/lib/public/AppFramework/Utility/ITimeFactory.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCP\AppFramework\Utility;
+
+
+/**
+ * Needed to mock calls to time()
+ * @since 8.0.0
+ */
+interface ITimeFactory {
+
+ /**
+ * @return int the result of a call to time()
+ * @since 8.0.0
+ */
+ public function getTime();
+
+}