From 41428a522f61b6adc10ecd6ce5b1753b397deb45 Mon Sep 17 00:00:00 2001 From: peterdamian Date: Sat, 18 Nov 2017 14:38:35 -0500 Subject: [PATCH] Header changes related to issue #602 --- developer_manual/android_library/examples.rst | 27 +++++---- .../android_library/library_installation.rst | 5 +- developer_manual/app/api.rst | 3 +- developer_manual/app/appdata.rst | 2 +- developer_manual/app/changelog.rst | 15 +++-- developer_manual/app/configuration.rst | 9 ++- developer_manual/app/container.rst | 30 ++++++---- developer_manual/app/controllers.rst | 60 ++++++++++++------- developer_manual/app/database.rst | 19 +++--- developer_manual/app/filesystem.rst | 5 +- developer_manual/app/hooks.rst | 18 ++++-- developer_manual/app/index.rst | 38 ++++++++---- developer_manual/app/init.rst | 11 ++-- developer_manual/app/js.rst | 10 ++-- developer_manual/app/l10n.rst | 14 +++-- developer_manual/app/middleware.rst | 3 +- developer_manual/app/repair.rst | 12 ++-- developer_manual/app/request.rst | 14 +++-- developer_manual/app/routes.rst | 14 +++-- developer_manual/app/settings.rst | 6 +- developer_manual/app/templates.rst | 8 ++- developer_manual/app/testing.rst | 3 +- developer_manual/app/theming.rst | 6 +- developer_manual/app/tutorial.rst | 39 ++++++++---- developer_manual/app/two-factor-provider.rst | 6 +- developer_manual/app/users.rst | 10 ++-- developer_manual/bugtracker/codereviews.rst | 1 + developer_manual/bugtracker/kanban.rst | 23 +++---- developer_manual/bugtracker/triaging.rst | 27 +++++---- developer_manual/client_apis/OCS/index.rst | 3 - developer_manual/client_apis/WebDAV/index.rst | 17 +----- developer_manual/client_apis/index.rst | 2 - developer_manual/core/configfile.rst | 1 + developer_manual/core/externalapi.rst | 16 +++-- developer_manual/core/ocs-share-api.rst | 30 +++++----- developer_manual/core/theming.rst | 40 ++++++++----- developer_manual/core/translation.rst | 13 ++-- developer_manual/core/unit-testing.rst | 21 +++---- developer_manual/design/content.rst | 4 +- developer_manual/design/html.rst | 10 ++-- developer_manual/design/icons.rst | 4 +- developer_manual/design/navigation.rst | 31 +++++----- developer_manual/design/popovermenu.rst | 13 ++-- developer_manual/design/settings.rst | 4 +- developer_manual/general/backporting.rst | 1 + developer_manual/general/code-of-conduct.rst | 1 + developer_manual/general/codingguidelines.rst | 15 +++++ developer_manual/general/debugging.rst | 3 +- developer_manual/general/devenv.rst | 13 ++-- developer_manual/general/performance.rst | 5 +- developer_manual/general/security.rst | 11 +++- developer_manual/index.rst | 2 +- user_manual/pim/sync_ios.rst | 1 + user_manual/pim/sync_osx.rst | 1 + user_manual/pim/sync_thunderbird.rst | 5 +- user_manual/session_management.rst | 6 +- user_manual/user_2fa.rst | 12 ++-- 57 files changed, 438 insertions(+), 285 deletions(-) diff --git a/developer_manual/android_library/examples.rst b/developer_manual/android_library/examples.rst index e5f767b3a..3748b5a52 100644 --- a/developer_manual/android_library/examples.rst +++ b/developer_manual/android_library/examples.rst @@ -1,3 +1,4 @@ +======== Examples ======== @@ -8,7 +9,7 @@ Start using the library; it is needed to init the object mClient that will be in charge of keeping the communication with the server. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -45,7 +46,7 @@ Authentication on the app is possible by 3 different methods: * Cookie (SAML-based single-sign-on) Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -74,7 +75,7 @@ Create a new folder on the cloud server, the info needed to be sent is the path of the new folder. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^   .. code-block:: java @@ -102,7 +103,7 @@ content of the root folder. As answer of this method, it will be received an array with all the files and folders stored in the selected folder. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -131,7 +132,7 @@ Get information related to a certain file or folder, information obtained is: ``filePath``, ``filename``, ``isDirectory``, ``size`` and ``date``. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -158,7 +159,7 @@ Delete a file or folder on the cloud server. The info needed is the path of folder/file to be deleted. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -186,7 +187,7 @@ file on the server and targetDirectory, path where the file will be stored on the device. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -223,7 +224,7 @@ where the file is stored on the device, remotePath, path where the file will be stored on the server and mimeType. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -263,7 +264,7 @@ When the parameter 'overwrite' is set to 'true', the file or folder is moved eve used by a different file or folder. This one will be replaced by the former. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^   .. code-block:: java @@ -289,7 +290,7 @@ Get information about what files and folder are shared by link (the object mClient contains the information about the server URL and account). Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -321,7 +322,7 @@ Boolean variable, getReshares, come from the Sharing api, from the moment it is not in use within the Nextcloud Android library. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -361,7 +362,7 @@ within the Nextcloud Android library. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java @@ -399,7 +400,7 @@ Stop sharing by link a file or a folder from your cloud server. The info needed is the object OCShare that you want to stop sharing by link. Code example -~~~~~~~~~~~~ +^^^^^^^^^^^^ .. code-block:: java diff --git a/developer_manual/android_library/library_installation.rst b/developer_manual/android_library/library_installation.rst index e66890c2d..e5930d3b0 100644 --- a/developer_manual/android_library/library_installation.rst +++ b/developer_manual/android_library/library_installation.rst @@ -1,3 +1,4 @@ +==================== Library Installation ==================== @@ -25,7 +26,7 @@ There are different methods to add an external library to a project, we will des Add the library as a Gradle dependency -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Simply open your:: @@ -39,7 +40,7 @@ and add the dependency:: Add the library project to your project as a Git submodule -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Basically get the code and compile it having it integrated via a Git submodule. diff --git a/developer_manual/app/api.rst b/developer_manual/app/api.rst index 3415c02a7..899311db5 100644 --- a/developer_manual/app/api.rst +++ b/developer_manual/app/api.rst @@ -48,7 +48,8 @@ Keep in mind that multiple apps will likely depend on the API interface once it /index.php/apps/myapp/api/1.0/resource Modifying the CORS headers -========================== +-------------------------- + By default the following values will be used for the preflighted OPTIONS request: * **Access-Control-Allow-Methods**: 'PUT, POST, GET, DELETE, PATCH' diff --git a/developer_manual/app/appdata.rst b/developer_manual/app/appdata.rst index 00afa5246..cd0941b45 100644 --- a/developer_manual/app/appdata.rst +++ b/developer_manual/app/appdata.rst @@ -35,7 +35,7 @@ Usage is almost trivial when your app is using the AppFramework. This gives your controller access to the IAppData simple filesystem of your app. The Simple Filesystem -===================== +--------------------- The `IAppData` uses the simple filesystem. This is a very simplified filesystem that will allow for easy mapping to for example memcaches. The filesystem has three elements: `root`, `folder`, `file`. diff --git a/developer_manual/app/changelog.rst b/developer_manual/app/changelog.rst index 2ce16aaef..4685ff0ce 100644 --- a/developer_manual/app/changelog.rst +++ b/developer_manual/app/changelog.rst @@ -5,13 +5,15 @@ Changelog .. sectionauthor:: Bernhard Posselt Deprecations -============ +------------ + This is a deprecation roadmap which lists all current deprecation targets and will be updated from release to release. This lists the year when a specific method or class will be removed. .. note:: Deprecations on interfaces also affect the implementing classes! 2018 ----- +^^^^ + * **OCP\\App::setActiveNavigationEntry** has been deprecated in favour of **\\OCP\\INavigationManager** * **OCP\\BackgroundJob::registerJob** has been deprecated in favour of **OCP\\BackgroundJob\\IJobList** * **OCP\\Contacts** functions has been deprecated in favour of **\\OCP\\Contacts\\IManager** @@ -43,7 +45,8 @@ This is a deprecation roadmap which lists all current deprecation targets and wi 2017 ----- +^^^^ + * **OCP\\IDb**: This interface and the implementing classes will be removed in favor of **OCP\\IDbConnection**. Various layers in between have also been removed to be consistent with the PDO classes. This leads to the following changes: * Replace all calls on the db using **getInsertId** with **lastInsertId** @@ -52,7 +55,8 @@ This is a deprecation roadmap which lists all current deprecation targets and wi * The **execute** method on **OCP\\AppFramework\\Db\\Mapper** no longer returns an instance of **OC_DB_StatementWrapper** but an instance of **PDOStatement** 2016 ----- +^^^^ + * The following methods have been moved into the **OCP\\Template::** class instead of being namespaced directly: * **OCP\\image_path** @@ -69,5 +73,6 @@ This is a deprecation roadmap which lists all current deprecation targets and wi * `OCP\\AppFramework\\Controller `_: methods **params**, **getParams**, **method**, **getUploadedFile**, **env**, **cookie**, **render** 2015 ----- +^^^^ + * `\\OC\\Preferences `_ and `\\OC_Preferences `_ diff --git a/developer_manual/app/configuration.rst b/developer_manual/app/configuration.rst index b83e3e0e3..2d633f2a8 100644 --- a/developer_manual/app/configuration.rst +++ b/developer_manual/app/configuration.rst @@ -41,7 +41,8 @@ The config that allows the app to set global, app and user settings can be injec } System values -============= +------------- + System values are saved in the :file:`config/config.php` and allow the app to modify and read the global configuration: .. code-block:: php @@ -74,7 +75,8 @@ System values are saved in the :file:`config/config.php` and allow the app to mo App values -========== +---------- + App values are saved in the database per app and are useful for setting global app settings: .. code-block:: php @@ -106,7 +108,8 @@ App values are saved in the database per app and are useful for setting global a } User values -=========== +----------- + User values are saved in the database per user and app and are good for saving user specific app settings: .. code-block:: php diff --git a/developer_manual/app/container.rst b/developer_manual/app/container.rst index 3eea09f89..4345578f6 100644 --- a/developer_manual/app/container.rst +++ b/developer_manual/app/container.rst @@ -14,7 +14,8 @@ If you are unfamiliar with this pattern, watch the following videos: .. _dependency-injection: Dependency Injection -==================== +-------------------- + Dependency Injection sounds pretty complicated but it just means: Don't put new dependencies in your constructor or methods but pass them in. So this: .. code-block:: php @@ -51,7 +52,8 @@ would turn into this by using Dependency Injection: Using a container -================= +----------------- + Passing dependencies into the constructor rather than instantiating them in the constructor has the following drawback: Every line in the source code where **new AuthorMapper** is being used has to be changed, once a new constructor argument is being added to it. The solution for this particular problem is to limit the **new AuthorMapper** to one file, the container. The container contains all the factories for creating these objects and is configured in :file:`lib/AppInfo/Application.php`. @@ -114,7 +116,7 @@ To add the app's classes simply open the :file:`lib/AppInfo/Application.php` and } How the container works -======================= +----------------------- The container works in the following way: @@ -154,12 +156,13 @@ So basically the container is used as a giant factory to build all the classes t Use automatic dependency assembly (recommended) -=============================================== +----------------------------------------------- In Nextcloud it is possible to omit the **lib/AppInfo/Application.php** and use automatic dependency assembly instead. How does automatic assembly work --------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Automatic assembly creates new instances of classes just by looking at the class name and its constructor parameters. For each constructor parameter the type or the variable name is used to query the container, e.g.: * **SomeType $type** will use **$container->query('SomeType')** @@ -198,7 +201,7 @@ So basically the following is now possible: .. note:: $AppName is resolved because the container registered a parameter under the key 'AppName' which will return the app id. The lookup is case sensitive so while $AppName will work correctly, using $appName as a constructor parameter will fail. How does it affect the request lifecycle ----------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * A request comes in * All apps' **routes.php** files are loaded @@ -211,7 +214,8 @@ How does it affect the request lifecycle * If the entry does not exist, the container is queried for OCA\\AppName\\Controller\\PageController and if no entry exists, the container tries to create the class by using reflection on its constructor parameters How does this affect controllers --------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The only thing that needs to be done to add a route and a controller method is now: **myapp/appinfo/routes.php** @@ -244,7 +248,8 @@ There is no need to wire up anything in **lib/AppInfo/Application.php**. Everyth How to deal with interface and primitive type parameters --------------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Interfaces and primitive types can not be instantiated, so the container can not automatically assemble them. The actual implementation needs to be wired up in the container: .. code-block:: php @@ -275,7 +280,8 @@ Interfaces and primitive types can not be instantiated, so the container can not } Predefined core services ------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ + The following parameter names and type hints can be used to inject core services instead of using **$container->getServer()->getServiceX()** Parameters: @@ -322,7 +328,8 @@ Types: * **OCP\\IUserSession** How to enable it ----------------- +^^^^^^^^^^^^^^^^ + To make use of this new feature, the following things have to be done: * **appinfo/info.xml** requires to provide another field called **namespace** where the namespace of the app is defined. The required namespace is the one which comes after the top level namespace **OCA\\**, e.g.: for **OCA\\MyBeautifulApp\\Some\\OtherClass** the needed namespace would be **MyBeautifulApp** and would be added to the info.xml in the following way: @@ -348,7 +355,8 @@ To make use of this new feature, the following things have to be done: .. note:: A namespace tag is required because you can not deduce the namespace from the app id Which classes should be added -============================= +----------------------------- + In general all of the app's controllers need to be registered inside the container. Then the following question is: What goes into the constructor of the controller? Pass everything into the controller constructor that matches one of the following criteria: * It does I/O (database, write/read to files) diff --git a/developer_manual/app/controllers.rst b/developer_manual/app/controllers.rst index b376edb72..ba98081d9 100644 --- a/developer_manual/app/controllers.rst +++ b/developer_manual/app/controllers.rst @@ -26,7 +26,8 @@ To create a controller, simply extend the Controller class and create a method t Connecting a controller and a route -=================================== +----------------------------------- + To connect a controller and a route the controller has to be registered in the :doc:`container` like this: .. code-block:: php @@ -83,7 +84,8 @@ This name is processed in the following way: * Now retrieve the service listed under **AuthorApiController** from the container, look up the parameters of the **someMethod** method in the request, cast them if there are PHPDoc type annotations and execute the **someMethod** method on the controller with those parameters. Getting request parameters -========================== +-------------------------- + Parameters can be passed in many ways: * Extracted from the URL using curly braces like **{key}** inside the URL (see :doc:`routes`) @@ -135,7 +137,8 @@ It is also possible to set default parameter values by using PHP default method Casting parameters ------------------- +^^^^^^^^^^^^^^^^^^ + URL, GET and application/x-www-form-urlencoded have the problem that every parameter is a string, meaning that:: ?doMore=false @@ -176,7 +179,8 @@ The following types will be cast: JSON parameters ---------------- +^^^^^^^^^^^^^^^ + It is possible to pass JSON using a POST, PUT or PATCH request. To do that the **Content-Type** header has to be set to **application/json**. The JSON is being parsed as an array and the first level keys will be used to pass in the arguments, e.g.:: POST /index.php/apps/myapp/authors @@ -210,7 +214,8 @@ It is possible to pass JSON using a POST, PUT or PATCH request. To do that the * } Reading headers, files, cookies and environment variables ---------------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Headers, files, cookies and environment variables can be accessed directly from the request object: .. code-block:: php @@ -236,7 +241,8 @@ Why should those values be accessed from the request object and not from the glo Reading and writing session variables -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + To set, get or modify session variables, the ISession object has to be injected into the controller. Then session variables can be accessed like this: @@ -277,7 +283,8 @@ Then session variables can be accessed like this: Setting cookies ---------------- +^^^^^^^^^^^^^^^ + Cookies can be set or modified directly on the response class: .. code-block:: php @@ -318,11 +325,13 @@ Cookies can be set or modified directly on the response class: Responses -========= +--------- + Similar to how every controller receives a request object, every controller method has to return a Response. This can be in the form of a Response subclass or in the form of a value that can be handled by a registered responder. JSON ----- +^^^^ + Returning JSON is simple, just pass an array to a JSONResponse: .. code-block:: php @@ -362,7 +371,8 @@ Because returning JSON is such a common task, there's even a shorter way to do t Why does this work? Because the dispatcher sees that the controller did not return a subclass of a Response and asks the controller to turn the value into a Response. That's where responders come in. Responders ----------- +^^^^^^^^^^ + Responders are short functions that take a value and return a response. They are used to return different kinds of responses based on a **format** parameter which is supplied by the client. Think of an API that is able to return both XML and JSON depending on if you call the URL with:: ?format=xml @@ -447,7 +457,8 @@ Because returning values works fine in case of a success but not in case of fail Templates ---------- +^^^^^^^^^ + A :doc:`template ` can be rendered by returning a TemplateResponse. A TemplateResponse takes the following parameters: * **appName**: tells the template engine in which app the template should be located @@ -481,7 +492,8 @@ A :doc:`template ` can be rendered by returning a TemplateResponse. A } Redirects ---------- +^^^^^^^^^ + A redirect can be achieved by returning a RedirectResponse: .. code-block:: php @@ -501,7 +513,8 @@ A redirect can be achieved by returning a RedirectResponse: } Downloads ---------- +^^^^^^^^^ + A file download can be triggered by returning a DownloadResponse: .. code-block:: php @@ -524,7 +537,8 @@ A file download can be triggered by returning a DownloadResponse: } Creating custom responses -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ + If no premade Response fits the needed usecase, it is possible to extend the Response base class and custom Response. The only thing that needs to be implemented is the **render** method which returns the result as string. Creating a custom XMLResponse class could look like this: @@ -554,7 +568,7 @@ Creating a custom XMLResponse class could look like this: } Streamed and lazily rendered responses --------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ By default all responses are rendered at once and sent as a string through middleware. In certain cases this is not a desirable behavior, for instance if you want to stream a file in order to save memory. To do that use the now available **OCP\\AppFramework\\Http\\StreamResponse** class: @@ -598,7 +612,7 @@ If you want to use a custom, lazily rendered response simply implement the inter .. note:: Because this code is rendered after several usually built in helpers, you need to take care of errors and proper HTTP caching by yourself. Modifying the Content Security Policy -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ By default Nextcloud disables all resources which are not served on the same domain, forbids cross domain requests and disables inline CSS and JavaScript by setting a `Content Security Policy `_. However if an app relies on third-party media or other features which are forbidden by the current policy the policy can be relaxed. @@ -650,7 +664,8 @@ The following policy for instance allows images, audio and videos from other dom OCS ---- +^^^ + .. note:: This is purely for compatibility reasons. If you are planning to offer an external API, go for a :doc:`api` instead. In order to ease migration from OCS API routes to the App Framework, an additional controller and response have been added. To migrate your API you can use the **OCP\\AppFramework\\OCSController** base class and return your data in the form of a DataResponse in the following way: @@ -702,7 +717,8 @@ Inside these are normal routes. Now your method will be reachable via ``/ocs/v2.php/apps//api/v1/shares`` Handling errors ---------------- +^^^^^^^^^^^^^^^ + Sometimes a request should fail, for instance if an author with id 1 is requested but does not exist. In that case use an appropriate `HTTP error code `_ to signal the client that an error occurred. Each response subclass has access to the **setStatus** method which lets you set an HTTP status code. To return a JSONResponse signaling that the author with id 1 has not been found, use the following code: @@ -730,7 +746,8 @@ Each response subclass has access to the **setStatus** method which lets you set } Authentication -============== +-------------- + By default every controller method enforces the maximum security, which is: * Ensure that the user is admin @@ -769,7 +786,8 @@ A controller method that turns off all checks would look like this: } Rate limiting -============= +------------- + Nextcloud supports rate limiting on a controller method basis. By default controller methods are not rate limited. Rate limiting should be used on expensive or security sensitive functions (e.g. password resets) to increase the overall security of your application. The native rate limiting will return a 429 status code to clients when the limit is reached and a default Nextcloud error page. When implementing rate limiting in your application, you should thus consider handling error situations where a 429 is returned by Nextcloud. @@ -802,7 +820,7 @@ A controller method that would allow five requests for logged-in users and one r } Brute-force protection -====================== +---------------------- Nextcloud supports brute-force protection on an action basis. By default controller methods are not protected. Brute-force protection should be used on security sensitive functions (e.g. login attempts) to increase the overall security of your application. diff --git a/developer_manual/app/database.rst b/developer_manual/app/database.rst index 5875e4dba..bc98bc6c4 100644 --- a/developer_manual/app/database.rst +++ b/developer_manual/app/database.rst @@ -42,7 +42,8 @@ Inside your database layer class you can now start running queries like: Mappers -======= +------- + The aforementioned example is the most basic way to write a simple database query but the more queries amass, the more code has to be written and the harder it will become to maintain it. To generalize and simplify the problem, split code into resources and create an **Entity** and a **Mapper** class for it. The mapper class provides a way to run SQL queries and maps the result onto the related entities. @@ -89,7 +90,7 @@ To create a mapper, inherit from the mapper base class and call the parent const public function authorNameCount($name) { - $sql = 'SELECT COUNT(*) AS `count` FROM `*PREFIX*myapp_authors` ' . + $sql = 'SELECT COUNT(*) AS `count` FROM `PREFIXmyapp_authors` ' . 'WHERE `name` = ?'; $stmt = $this->execute($sql, [$name]); @@ -113,7 +114,8 @@ or:: Entities -======== +-------- + Entities are data objects that carry all the table's information for one row. Every Entity has an **id** field by default that is set to the integer type. Table rows are mapped from lower case and underscore separated names to *lowerCamelCase* attributes: * **Table column name**: phone_number @@ -140,7 +142,8 @@ Entities are data objects that carry all the table's information for one row. Ev } Types ------ +^^^^^ + The following properties should be annotated by types, to not only assure that the types are converted correctly for storing them in the database (e.g. PHP casts false to the empty string which fails on PostgreSQL) but also for casting them when they are retrieved from the database. The following types can be added for a field: @@ -150,7 +153,8 @@ The following types can be added for a field: * boolean Accessing attributes --------------------- +^^^^^^^^^^^^^^^^^^^^ + Since all attributes should be protected, getters and setters are automatically generated for you: @@ -173,7 +177,7 @@ Since all attributes should be protected, getters and setters are automatically $author->getPhoneNumber() // null Custom attribute to database column mapping -------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ By default each attribute will be mapped to a database column by a certain convention, e.g. **phoneNumber** will be mapped to the column **phone_number** and vice versa. Sometimes it is needed though to map attributes to @@ -215,7 +219,8 @@ mapping, simply override the **columnToProperty** and **propertyToColumn** metho Slugs ------ +^^^^^ + Slugs are used to identify resources in the URL by a string rather than integer id. Since the URL allows only certain values, the entity base class provides a slugify method for it: .. code-block:: php diff --git a/developer_manual/app/filesystem.rst b/developer_manual/app/filesystem.rst index 5ad6edcec..2c396781b 100644 --- a/developer_manual/app/filesystem.rst +++ b/developer_manual/app/filesystem.rst @@ -40,7 +40,8 @@ Filesystem classes can be injected from the ServerContainer by calling the metho } Writing to a file -================= +----------------- + All methods return a Folder object on which files and folders can be accessed, or filesystem operations can be performed relatively to their root. For instance for writing to file:`nextcloud/data/myfile.txt` you should get the root folder and use: @@ -78,7 +79,7 @@ All methods return a Folder object on which files and folders can be accessed, o } Reading from a file -=================== +------------------- Files and folders can also be accessed by id, by calling the **getById** method on the folder. diff --git a/developer_manual/app/hooks.rst b/developer_manual/app/hooks.rst index 5369d2e1f..404fac065 100644 --- a/developer_manual/app/hooks.rst +++ b/developer_manual/app/hooks.rst @@ -68,7 +68,8 @@ The hook logic should be in a separate class that is being registered in the :do } Available hooks -=============== +--------------- + The scope is the first parameter that is passed to the **listen** method, the second parameter is the method and the third one the callback that should be executed once the hook is being called, e.g.: .. code-block:: php @@ -95,7 +96,8 @@ Hooks can also be removed by using the **removeListener** method on the object: The following hooks are available: Session -------- +^^^^^^^ + Injectable from the ServerContainer by calling the method **getUserSession()**. Hooks available in scope **\\OC\\User**: @@ -112,7 +114,8 @@ Hooks available in scope **\\OC\\User**: * **logout** () UserManager ------------ +^^^^^^^^^^^ + Injectable from the ServerContainer by calling the method **getUserManager()**. Hooks available in scope **\\OC\\User**: @@ -125,7 +128,8 @@ Hooks available in scope **\\OC\\User**: * **postCreateUser** (\\OC\\User\\User $user, string $password) GroupManager ------------- +^^^^^^^^^^^^ + Hooks available in scope **\\OC\\Group**: * **preAddUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user) @@ -138,7 +142,8 @@ Hooks available in scope **\\OC\\Group**: * **postCreate** (\\OC\\Group\\Group $group) Filesystem Root ---------------- +^^^^^^^^^^^^^^^ + Injectable from the ServerContainer by calling the method **getRootFolder()**, **getUserFolder()** or **getAppFolder()**. Filesystem hooks available in scope **\\OC\\Files**: @@ -157,7 +162,8 @@ Filesystem hooks available in scope **\\OC\\Files**: * **postRename** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target) Filesystem Scanner ------------------- +^^^^^^^^^^^^^^^^^^ + Filesystem scanner hooks available in scope **\\OC\\Files\\Utils\\Scanner**: * **scanFile** (string $absolutePath) diff --git a/developer_manual/app/index.rst b/developer_manual/app/index.rst index f7301d3ca..2532cfcdc 100644 --- a/developer_manual/app/index.rst +++ b/developer_manual/app/index.rst @@ -46,7 +46,7 @@ App Development .. sectionauthor:: Bernhard Posselt Intro -===== +----- Before you start, please check if there already is a similar app in the `App Store `_ or the `GitHub organisation `_ that you could contribute to. Also, feel free to communicate your idea and plans in the `forum `_ so other contributors might join in. @@ -72,7 +72,8 @@ For enhanced security it is also possible to sign your code: * :doc:`code_signing` App development -=============== +--------------- + Take a look at the changes in this version: * :doc:`changelog` @@ -88,7 +89,8 @@ Inner parts of an app: * :doc:`classloader` Requests --------- +^^^^^^^^ + How a request is being processed: * :doc:`request` @@ -98,7 +100,8 @@ How a request is being processed: * :doc:`controllers` | :doc:`api` View ----- +^^^^ + The app's presentation layer: * :doc:`templates` @@ -108,7 +111,8 @@ The app's presentation layer: * :doc:`theming` Storage -------- +^^^^^^^ + Create database tables, run Sql queries, store/retrieve configuration information and access the filesystem: * :doc:`schema` @@ -117,7 +121,8 @@ Create database tables, run Sql queries, store/retrieve configuration informatio * :doc:`filesystem` Authentication & Users ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ + Creating, deleting, updating, searching, login and logout: * :doc:`users` @@ -127,43 +132,50 @@ Writing a two-factor auth provider: * :doc:`two-factor-provider` Hooks ------ +^^^^^ + Listen on events like user creation and execute code: * :doc:`hooks` Background Jobs ---------------- +^^^^^^^^^^^^^^^ + Periodically run code in the background: * :doc:`backgroundjobs` Settings ---------------- +^^^^^^^^ + An app can register both admin settings as well as personal settings: * :doc:`settings` Logging -------- +^^^^^^^ + Log to the :file:`data/nextcloud.log`: * :doc:`logging` Repair steps ------------- +^^^^^^^^^^^^ + Repair steps can be used to run code at various stages in app installation, uninstallation, migration ... * :doc:`repair` Testing -------- +^^^^^^^ + Write automated tests to ensure stability and ease maintenance: * :doc:`testing` PHPDoc Class Documentation --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ + Nextcloud class and function documentation: * `Nextcloud App API `_ diff --git a/developer_manual/app/init.rst b/developer_manual/app/init.rst index 6f95e00ae..34b24b519 100644 --- a/developer_manual/app/init.rst +++ b/developer_manual/app/init.rst @@ -6,7 +6,7 @@ Navigation and Pre-App configuration Adding a navigation entry -========================= +------------------------- Navigation entries for apps can be created by adding a navigation section to the :file:`appinfo/info.xml` file, containing the name, order and route the navigation entry should link to. For details on the XML schema check the `app store documentation `_. @@ -20,7 +20,7 @@ Navigation entries for apps can be created by adding a navigation section to the Further pre-app configuration -============================= +----------------------------- The :file:`appinfo/app.php` is the first file that is loaded and executed in Nextcloud. Depending on the purpose of the app it is usually used to setup things that need to be available on every request to the server, like :doc:`backgroundjobs` and :doc:`hooks` registrations. This is how an example :file:`appinfo/app.php` could look like: @@ -45,12 +45,13 @@ Although it is also possible to include :doc:`js` or :doc:`css` for other apps b \OCP\Util::addStyle('myapp', 'style'); // include css/style.css for every app Best practice -============= +------------- + A common way to have a cleaner code structure is to create a class Application in :file:`lib/AppInfo/Application.php` that will then execute your setup of hooks or background tasks. You can then just call it in your :file:`appinfo/app.php`. That way you can also make use of Nextclouds dependency injection feature and properly test those methods. appinfo/app.php ---------------- +^^^^^^^^^^^^^^^ .. code-block:: php @@ -61,7 +62,7 @@ appinfo/app.php lib/AppInfo/Application.php ---------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: php diff --git a/developer_manual/app/js.rst b/developer_manual/app/js.rst index c0782b8fb..4ba47377e 100644 --- a/developer_manual/app/js.rst +++ b/developer_manual/app/js.rst @@ -32,7 +32,8 @@ listen to the ``OCA\Files::loadAdditionalScripts`` event: Sending the CSRF token -====================== +---------------------- + If any other JavaScript request library than jQuery is being used, the requests need to send the CSRF token as an HTTP header named **requesttoken**. The token is available in the global variable **oc_requesttoken**. For AngularJS the following lines would need to be added: @@ -45,7 +46,8 @@ For AngularJS the following lines would need to be added: Generating URLs -=============== +--------------- + To send requests to Nextcloud the base URL where Nextcloud is currently running is needed. To get the base URL use: .. code-block:: js @@ -60,13 +62,13 @@ Full URLs can be generated by using: Extending core parts -==================== +-------------------- It is possible to extend components of the core web UI. The following examples should show how this is possible. Extending the "new" menu in the files app ------------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. versionadded:: 9.0 diff --git a/developer_manual/app/l10n.rst b/developer_manual/app/l10n.rst index 3fccb8f05..d86e3f4e7 100644 --- a/developer_manual/app/l10n.rst +++ b/developer_manual/app/l10n.rst @@ -7,7 +7,8 @@ Translation Nextcloud's translation system is powered by `Transifex `_. To start translating sign up and enter a group. If your community app should be added to Transifex contact one of the translation teams `in the forums `_ to set it up for you. PHP -=== +--- + Should it ever be needed to use localized strings on the server-side, simply inject the L10N service from the ServerContainer into the needed constructor: @@ -86,7 +87,8 @@ Strings can then be translated in the following way: Templates -========= +--------- + In every template the global variable **$l** can be used to translate the strings using its methods **t()** and **n()**: .. code-block:: php @@ -96,7 +98,8 @@ In every template the global variable **$l** can be used to translate the string JavaScript -========== +---------- + There is a global function **t()** available for translating strings. The first argument is your app name, the second argument is the string to translate. .. code-block:: js @@ -106,7 +109,8 @@ There is a global function **t()** available for translating strings. The first For advanced usage, refer to the source code **core/js/l10n.js**; **t()** is bind to **OC.L10N.translate()**. Hints -===== +----- + In case some translation strings may be translated wrongly because they have multiple meanings, you can add hints which will be shown in the Transifex web-interface: .. code-block:: php @@ -121,7 +125,7 @@ In case some translation strings may be translated wrongly because they have mul Creating your own translatable files -==================================== +------------------------------------ If Transifex is not the right choice or the app is not accepted for translation, generate the gettext strings by yourself by creating an :file:`l10n/` directory diff --git a/developer_manual/app/middleware.rst b/developer_manual/app/middleware.rst index 102e68bf5..479530e6f 100644 --- a/developer_manual/app/middleware.rst +++ b/developer_manual/app/middleware.rst @@ -76,7 +76,8 @@ The middleware can be registered in the :doc:`container` and added using the **r Parsing annotations -=================== +------------------- + Sometimes it is useful to conditionally execute code before or after a controller method. This can be done by defining custom annotations. An example would be to add a custom authentication method or simply add an additional header to the response. To access the parsed annotations, inject the **ControllerMethodReflector** class: .. code-block:: php diff --git a/developer_manual/app/repair.rst b/developer_manual/app/repair.rst index 3a71965df..c539ab260 100644 --- a/developer_manual/app/repair.rst +++ b/developer_manual/app/repair.rst @@ -11,7 +11,8 @@ steps because they are frequently used to fix things automatically. Creating a repair step -====================== +---------------------- + A repair step is an implementation of the ``OCP\Migration\IRepairStep`` interface. By convention these classes are placed in the **lib/Migration** directory. The following repairstep will log a message when executed. @@ -50,7 +51,8 @@ The following repairstep will log a message when executed. } Outputting information -~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^ + A repair step can generate information while running, using the ``OCP\Migration\IOutput`` parameter to the ``run`` method. Using the ``info`` and ``warning`` methods a message can be shown in the console. @@ -78,7 +80,8 @@ The following function will sleep for 10 seconds and show the progress: } Register a repair-step -====================== +---------------------- + To register a repair-step in Nextcloud you have to define the repair-setp in the ``info.xml`` file. The following example registers a repair-step which will be executed after installation of the app: @@ -101,7 +104,8 @@ of the app: Repair-step types -================= +----------------- + The following repair steps are available: * ``install`` This repair step will be executed when installing the app. This means it is executed every time the app is enabled (using the Web interface or the CLI). diff --git a/developer_manual/app/request.rst b/developer_manual/app/request.rst index 7753490e9..180b059d7 100644 --- a/developer_manual/app/request.rst +++ b/developer_manual/app/request.rst @@ -14,7 +14,8 @@ A typical HTTP request consists of the following: The following sections will present an overview over how that request is being processed to provide an in depth view over how Nextcloud works. If you are not interested in the internals or don't want to execute anything before and after your controller, feel free to skip this section and continue directly with defining :doc:`your app's routes `. Front controller -================ +---------------- + In the beginning, all requests are sent to Nextcloud's :file:`index.php` which in turn executes :file:`lib/base.php`. This file inspects the HTTP headers, abstracts away differences between different Web servers and initializes the basic classes. Afterwards the basic apps are being loaded in the following order: * Authentication backends @@ -31,11 +32,13 @@ Afterwards the following steps are performed: * Execute the router Router -====== +------ + The router parses the :doc:`app's routing files ` (:file:`appinfo/routes.php`), inspects the request's **method** and **url**, queries the controller from the :doc:`container` and then passes control to the dispatcher. The dispatcher is responsible for running the hooks (called Middleware) before and after the controller, executing the controller method and rendering the output. Middleware -========== +---------- + A :doc:`Middleware ` is a convenient way to execute common tasks such as custom authentication before or after a :doc:`controller method ` is being run. You can execute code at the following locations: * before the call of the controller method @@ -44,11 +47,12 @@ A :doc:`Middleware ` is a convenient way to execute common tasks suc * before the output is rendered Container -========= +--------- + The :doc:`container` is the place where you define all of your classes and in particular all of your controllers. The container is responsible for assembling all of your objects (instantiating your classes) that should only have one single instance without relying on globals or singletons. If you want to know more about why you should use it and what the benefits are, read up on the topic in :doc:`container`. Controller -========== +---------- The :doc:`controller ` contains the code that you actually want to run after a request has come in. Think of it like a callback that is executed if everything before went fine. diff --git a/developer_manual/app/routes.rst b/developer_manual/app/routes.rst index c3aed51a3..b825255fb 100644 --- a/developer_manual/app/routes.rst +++ b/developer_manual/app/routes.rst @@ -26,7 +26,7 @@ The route array contains the following parts: * **defaults** (Optional): If this setting is given, a default value will be assumed for each URL parameter which is not present. The default values are passed in as a key => value par array Extracting values from the URL -============================== +------------------------------ It is possible to extract values from the URL to allow RESTful URL design. To extract a value, you have to wrap it inside curly braces: @@ -53,7 +53,8 @@ The identifier used inside the route is being passed into controller method by r .. _matching-suburls: Matching subURLs -================ +---------------- + Sometimes it is needed to match more than one URL fragment. An example would be to match a request for all URLs that start with **OPTIONS /index.php/apps/myapp/api**. To do this, use the **requirements** parameter in your route which is an array containing pairs of **'key' => 'regex'**: .. code-block:: php @@ -76,7 +77,8 @@ Sometimes it is needed to match more than one URL fragment. An example would be } Default values for subURL -========================== +------------------------- + Apart from matching requirements, a subURL may also have a default value. Say you want to support pagination (a 'page' parameter) for your **/posts** subURL that displays posts entries list. You may set a default value for the 'page' parameter, that will be used if not already set in the URL. Use the **defaults** parameter in your route which is an array containing pairs of **'urlparameter' => 'defaultvalue'**: .. code-block:: php @@ -103,7 +105,8 @@ Apart from matching requirements, a subURL may also have a default value. Say yo } Registering resources -===================== +--------------------- + When dealing with resources, writing routes can become quite repetitive since most of the time routes for the following tasks are needed: * Get all entries @@ -143,7 +146,8 @@ can be abbreviated by using the **resources** key: ]; Using the URLGenerator -======================== +---------------------- + Sometimes it is useful to turn a route into a URL to make the code independent from the URL design or to generate a URL for an image in **img/**. Inside the PageController the URL generator can be injected by adding it to the constructor, which will allow to use it to generate a URL for a redirect. For more details on that see the :ref:`dependency-injection` reference. .. code-block:: php diff --git a/developer_manual/app/settings.rst b/developer_manual/app/settings.rst index d91f65e9d..9a2f4c4a1 100644 --- a/developer_manual/app/settings.rst +++ b/developer_manual/app/settings.rst @@ -15,7 +15,7 @@ For example, in the **Sharing** section are only settings (built-in and of apps) related to sharing. Settings Form -============= +------------- For the settings form, three things are necessary: @@ -200,7 +200,7 @@ implementation of the **user_ldap** app. Section -======= +------- It is also possible that an app registers its own section. This should be done only if there is not fitting corresponding section and the apps settings form @@ -263,7 +263,7 @@ An example implementation of the ISection interface: Also the section must be registered in the app's info.xml. Personal --------- +^^^^^^^^ Registering personal settings follows and old style yet. Within the app intialisation (e.g. in appinfo/app.php) a method must be called: diff --git a/developer_manual/app/templates.rst b/developer_manual/app/templates.rst index 4af19f0c0..29b319e61 100644 --- a/developer_manual/app/templates.rst +++ b/developer_manual/app/templates.rst @@ -28,7 +28,7 @@ Printing values is done by using the **p()** function, printing HTML is done by Including templates -=================== +------------------- Templates can also include other templates by using the **$this->inc('templateName')** method. @@ -48,7 +48,8 @@ The parent variables will also be available in the included templates, but shoul inc('other_template', array('variable' => 'value'))); ?> Including CSS and JavaScript -============================ +---------------------------- + To include CSS or JavaScript use the **style** and **script** functions: .. code-block:: php @@ -59,7 +60,8 @@ To include CSS or JavaScript use the **style** and **script** functions: Including images -================ +---------------- + To generate links to images use the **image_path** function: .. code-block:: php diff --git a/developer_manual/app/testing.rst b/developer_manual/app/testing.rst index 0f16e88cc..882fb2de5 100644 --- a/developer_manual/app/testing.rst +++ b/developer_manual/app/testing.rst @@ -9,7 +9,8 @@ All PHP classes can be tested with `PHPUnit `_, JavaScript c PHP -=== +--- + The PHP tests go into the **tests/** directory and PHPUnit can be run with:: phpunit tests/ diff --git a/developer_manual/app/theming.rst b/developer_manual/app/theming.rst index 353144134..3419d55c5 100644 --- a/developer_manual/app/theming.rst +++ b/developer_manual/app/theming.rst @@ -7,7 +7,7 @@ Theming support The Nextcloud theming app offers some tools for app developers to ensure that apps also match the themed look. CSS classes -=========== +----------- * **.nc-theming-main-background** Background in theming color * **.nc-theming-main-text** Text in theming color @@ -15,7 +15,7 @@ CSS classes JavaScript -========== +---------- When the theming app is enabled, it provides the **OCA.Theming** object. It can be used to handle themed instances differently. @@ -35,7 +35,7 @@ The following information is available: * **OCA.Theming.url** Instance web address Icons -===== +----- The theming app will automatically generate favicons and home screen icons for each app by using the icon `img/app.svg` inside of the app folder. Any custom diff --git a/developer_manual/app/tutorial.rst b/developer_manual/app/tutorial.rst index 971ab407b..8611ff889 100644 --- a/developer_manual/app/tutorial.rst +++ b/developer_manual/app/tutorial.rst @@ -8,7 +8,8 @@ This tutorial will outline how to create a very simple notes app. The finished a Setup -===== +----- + First the :doc:`development environment <../general/devenv>` needs to be set up. This can be done by either `downloading the zip from the website `_ or cloning it directly from GitHub:: git clone git@github.com:nextcloud/server.git --branch $BRANCH @@ -38,7 +39,8 @@ Download the compressed file that contains the generated app and extract it into The first basic app is now available at ``http://localhost:8080/index.php/apps/yourappid/`` Routes & Controllers -==================== +-------------------- + A typical web application consists of server side and client side code. The glue between those two parts are the URLs. In case of the notes app the following URLs will be used: * **GET /**: Returns the interface in HTML @@ -205,7 +207,8 @@ Since those 5 routes are so common, they can be abbreviated by adding a resource ]; Database -======== +-------- + Now that the routes are set up and connected the notes should be saved in the database. To do that first create a :doc:`database schema ` by creating **ownnotes/appinfo/database.xml**: .. code-block:: xml @@ -334,7 +337,8 @@ Entities are returned from so called :doc:`Mappers `. Let's create one .. note:: The first parent constructor parameter is the database layer, the second one is the database table and the third is the entity on which the result should be mapped onto. Insert, delete and update methods are already implemented. Connect Database & Controllers -============================== +------------------------------ + The mapper which provides the database access is finished and can be passed into the controller. You can pass in the mapper by adding it as a type hinted parameter. Nextcloud will figure out how to :doc:`assemble them by itself `. Additionally we want to know the userId of the currently logged in user. Simply add a **$UserId** parameter to the constructor (case sensitive!). To do that open **ownnotes/lib/Controller/NoteController.php** and change it to the following: @@ -439,7 +443,8 @@ You can pass in the mapper by adding it as a type hinted parameter. Nextcloud wi This is all that is needed on the server side. Now let's progress to the client side. Making things reusable and decoupling controllers from the database -=================================================================== +------------------------------------------------------------------- + Let's say our app is now on the app store and and we get a request that we should save the files in the filesystem which requires access to the filesystem. The filesystem API is quite different from the database API and throws different exceptions, which means we need to rewrite everything in the **NoteController** class to use it. This is bad because a controller's only responsibility should be to deal with incoming Http requests and return Http responses. If we need to change the controller because the data storage was changed the code is probably too tightly coupled and we need to add another layer in between. This layer is called **Service**. @@ -662,11 +667,13 @@ Now we can wire up the trait and the service inside the **NoteController**: Great! Now the only reason that the controller needs to be changed is when request/response related things change. Writing a test for the controller (recommended) -=============================================== +----------------------------------------------- + Tests are essential for having happy users and a carefree life. No one wants their users to rant about your app breaking their Nextcloud or being buggy. To do that you need to test your app. Since this amounts to a ton of repetitive tasks, we need to automate the tests. Unit Tests ----------- +^^^^^^^^^^ + A unit test is a test that tests a class in isolation. It is very fast and catches most of the bugs, so we want many unit tests. Because Nextcloud uses :doc:`Dependency Injection ` to assemble your app, it is very easy to write unit tests by passing mocks into the constructor. A simple test for the update method can be added by adding this to **ownnotes/tests/Unit/Controller/NoteControllerTest.php**: @@ -807,6 +814,7 @@ If `PHPUnit is installed `_ we can run the tests inside **o Integration Tests ----------------- + Integration tests are slow and need a fully working instance but make sure that our classes work well together. Instead of mocking out all classes and parameters we can decide whether to use full instances or replace certain classes. Because they are slow we don't want as many integration tests as unit tests. In our case we want to create an integration test for the udpate method without mocking out the **NoteMapper** class so we actually write to the existing database. @@ -881,7 +889,8 @@ To run the integration tests change into the **ownnotes** directory and run:: phpunit -c phpunit.integration.xml Adding a RESTful API (optional) -=============================== +------------------------------- + A :doc:`RESTful API ` allows other apps such as Android or iPhone apps to access and change your notes. Since syncing is a big core component of Nextcloud it is a good idea to add (and document!) your own RESTful API. Because we put our logic into the **NoteService** class it is very easy to reuse it. The only pieces that need to be changed are the annotations which disable the CSRF check (not needed for a REST call usually) and add support for `CORS `_ so your API can be accessed from other webapps. @@ -1021,7 +1030,8 @@ Since the **NoteApiController** is basically identical to the **NoteController** } Adding JavaScript and CSS -========================= +------------------------- + To create a modern webapp you need to write :doc:`JavaScript`. You can use any JavaScript framework but for this tutorial we want to keep it as simple as possible and therefore only include the templating library `handlebarsjs `_. `Download the file `_ into **ownnotes/js/handlebars.js** and include it at the very top of **ownnotes/templates/main.php** before the other scripts and styles: .. code-block:: php @@ -1032,7 +1042,8 @@ To create a modern webapp you need to write :doc:`JavaScript`. You can use a .. note:: jQuery is included by default on every page. Creating a navigation -===================== +--------------------- + The template file **ownnotes/templates/part.navigation.php** contains the navigation. Nextcloud defines many handy :doc:`CSS styles ` which we are going to reuse to style the navigation. Adjust the file to contain only the following code: .. note:: **$l->t()** is used to make your strings :doc:`translatable ` and **p()** is used :doc:`to print escaped HTML ` @@ -1065,7 +1076,8 @@ The template file **ownnotes/templates/part.navigation.php** contains the naviga
    Creating the content -==================== +-------------------- + The template file **ownnotes/templates/part.content.php** contains the content. It will just be a textarea and a button, so replace the content with the following: .. code-block:: php @@ -1082,7 +1094,7 @@ The template file **ownnotes/templates/part.content.php** contains the content.
    Wiring it up -============ +------------ When the page is loaded we want all the existing notes to load. Furthermore we want to display the current note when you click on it in the navigation, a note should be deleted when we click the deleted button and clicking on **New note** should create a new note. To do that open **ownnotes/js/script.js** and replace the example code with the following: @@ -1294,7 +1306,8 @@ When the page is loaded we want all the existing notes to load. Furthermore we w Apply finishing touches -======================= +----------------------- + Now the only thing left is to style the textarea in a nicer fashion. To do that open **ownnotes/css/style.css** and replace the content with the following :doc:`CSS ` code: .. code-block:: css diff --git a/developer_manual/app/two-factor-provider.rst b/developer_manual/app/two-factor-provider.rst index a9ebc4f75..0a0c8181e 100644 --- a/developer_manual/app/two-factor-provider.rst +++ b/developer_manual/app/two-factor-provider.rst @@ -10,7 +10,8 @@ code was taken from the `two-factor test app`_. .. _`two-factor test app`: https://github.com/ChristophWurst/twofactor_test Implementing a simple two-factor auth provider -============================================== +---------------------------------------------- + Two-factor auth providers must implement the ``OCP\Authentication\TwoFactorAuth\IProvider`` interface. The example below shows a minimalistic example of such a provider. @@ -94,7 +95,8 @@ example below shows a minimalistic example of such a provider. } Registering a two-factor auth provider -====================================== +-------------------------------------- + You need to inform the Nextcloud core that the app provides two-factor auth functionality. Two-factor providers are registered via ``info.xml``. diff --git a/developer_manual/app/users.rst b/developer_manual/app/users.rst index 94898681d..52c4a4fe7 100644 --- a/developer_manual/app/users.rst +++ b/developer_manual/app/users.rst @@ -41,7 +41,8 @@ Users can be managed using the UserManager which is injected from the ServerCont Creating users -============== +-------------- + Creating a user is done by passing a username and password to the create method: .. code-block:: php @@ -64,7 +65,8 @@ Creating a user is done by passing a username and password to the create method: } Modifying users -=============== +--------------- + Users can be modified by getting a user by the userId or by a search pattern. The returned user objects can then be used to: * Delete them @@ -104,7 +106,8 @@ Users can be modified by getting a user by the userId or by a search pattern. Th } User Session Information -======================== +------------------------ + To login, logout or getting the currently logged in user, the UserSession has to be injected from the ServerContainer: .. code-block:: php @@ -170,4 +173,3 @@ Then users can be logged in by using: } } - diff --git a/developer_manual/bugtracker/codereviews.rst b/developer_manual/bugtracker/codereviews.rst index 4a4deeff8..1e04c7df0 100644 --- a/developer_manual/bugtracker/codereviews.rst +++ b/developer_manual/bugtracker/codereviews.rst @@ -1,3 +1,4 @@ +====================== Code Reviews on GitHub ====================== diff --git a/developer_manual/bugtracker/kanban.rst b/developer_manual/bugtracker/kanban.rst index c5fd1bac6..4785ce7e3 100644 --- a/developer_manual/bugtracker/kanban.rst +++ b/developer_manual/bugtracker/kanban.rst @@ -1,3 +1,4 @@ +=================== Development process =================== @@ -14,7 +15,7 @@ The following list shows what the labels mean in the life-cycle and will hopefully help you decide how to label an issue. Backlog -~~~~~~~ +^^^^^^^ Why do we have it? To keep us focused on finishing issues that we started, new issues will be @@ -38,7 +39,7 @@ Who is Assigned? to determine the responsible developer. Concept -~~~~~~~ +^^^^^^^ Why do we have it? Our think before you act phase serves two purposes. A Bug is in the concept @@ -67,7 +68,7 @@ Who is Assigned? The maintainer that feels responsible for the issue. To Develop -~~~~~~~~~~ +^^^^^^^^^^ Why do we have it? Now that we have a plan, any developer can pick an issue from this column and @@ -90,7 +91,7 @@ Who is Assigned? No one. Especially not if you are working on something else! Developing -~~~~~~~~~~ +^^^^^^^^^^ Why do we have it? This is where the magic happens. If it’s a Bug the fix will be submitted as a @@ -115,7 +116,7 @@ Who is Assigned? The most active developer should assign himself. To Review -~~~~~~~~~ +^^^^^^^^^ Why do we have it? Instead of directly committing to master we agree that **a second set of eyes @@ -138,7 +139,7 @@ Who is Assigned? No one. Especially not if you are working on something else! Reviewing -~~~~~~~~~ +^^^^^^^^^ Why do we have it? With the Gherkin Scenario from the Concept Phase reviewers have a checklist to @@ -163,7 +164,7 @@ Who is Assigned? The most active reviewer should assign himself. To Release -~~~~~~~~~~ +^^^^^^^^^^ Why do we have it? This is a list of issues that will make it into the next release. It serves @@ -202,7 +203,7 @@ Other Labels ------------ Priority Labels -~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^ * Panic should be used with caution. It is reserved for Bugs that would result in the loss of files or other user data. An Enhancement marked as Panic is @@ -223,21 +224,21 @@ Priority Labels it to the developer in charge of that part. App Labels -~~~~~~~~~~ +^^^^^^^^^^ In the apps repository there are labels like ``app:gallery`` and ``app:calendar``. The ``app:`` prefix is used to allow developers to filter issues related to a specific app. Resolution Status -~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^ * Fixed – Should be assigned to issues in to Release * Won’t fix – Reason is given as a comment * Duplicate – Corresponding bug is given in a comment (using #guthubissuenumber) Misc Labels -~~~~~~~~~~~ +^^^^^^^^^^^ * Needs info – Either from a developer or the bug reporter. This is nearly as severe as Panic, because no further action can be taken diff --git a/developer_manual/bugtracker/triaging.rst b/developer_manual/bugtracker/triaging.rst index fe57f47be..9162049ef 100644 --- a/developer_manual/bugtracker/triaging.rst +++ b/developer_manual/bugtracker/triaging.rst @@ -9,13 +9,15 @@ Nextcloud Bug Triaging Bug Triaging is the process of checking bug reports to see if they are still valid (the problem might be solved since the bug was reported), reproducing them when possible (to make sure it really is a Nextcloud issue and not a configuration problem) and in general making sure the bug is useful for a developer who wants to fix it. If the bug is not useful and can't be augmented by the original reporter or the triaging contributor, it has to be closed. Why do you want to join -======================= +----------------------- + Helping to bring the number of issues down makes it easier for developers to spend their time productively and bug triagers thus **contribute greatly to Nextcloud development**! Triaging a bug doesn’t take long so the work comes in small chunks and you don’t need many skills, just some patience and sometimes perseverance. Bug triagers who contribute significantly should ask to be listed as an active contributor on the `nextcloud.com `_ page! How do you triage bugs -====================== +---------------------- + The process of checking, reproducing and closing invalid issues is called ‘bug triaging‘. Issues can be divided in one of three kinds: 1. Bugs or feature requests which come with all needed information to allow a developer to fix or work on them @@ -32,7 +34,7 @@ Triaging follows these steps: * Find the next bug-to-be-dealt-with and repeat! General considerations -====================== +---------------------- * You need a `GitHub account `_ to contribute to bug triaging. * If you are not familiar with the GitHub issue tracker interface (which is used by Nextcloud to handle bug reports), you `may find this guide useful `_. @@ -44,7 +46,7 @@ General considerations To be able to tag and close issues, you need to have access to the repository. For the core and sync app repositories this also means having signed the contributor agreement. However, this isn't really needed for triaging as you can comment after you're done triaging and somebody else can execute those actions. Finding bugs to triage -====================== +---------------------- GitHub offers several search queries which can be useful to find a list of bugs which deserve a closer look: @@ -59,7 +61,7 @@ Once you have picked an issue, add a comment that you've started triaging: "I am triaging this bug" Checking if the issue is useful -=============================== +------------------------------- Much content from https://community.kde.org/Guidelines_and_HOWTOs/Bug_triaging @@ -71,7 +73,8 @@ The goal of triaging is to have only useful bug reports for the developers. And Let's go over each step. Finding duplicates ------------------- +^^^^^^^^^^^^^^^^^^ + To find duplicates, the search tool in GitHub is your first stop. In `this screen `_ you can easily search for a few keywords from the bug report. If you find other bugs with the same content, decide what the best bug report is (often the oldest or the one where one or more developers have already started to engage and discuss the problem). That is the 'master' bug report, you can now close the other one (or comment that it can be closed as duplicate). If the bug report you were reviewing contains additional information, you can add that information to the 'master' bug report in a comment. Mention this bug report (using #) so a developer can look up the original, closed, report and perhaps ask the initial reporter there for additional information. @@ -85,7 +88,8 @@ When the issue is a feature request, you can be helpful in the same way: merge r .. note:: Often our GitHub issue tracker is a place for discussions about solutions. Be friendly, inclusive and respect other people's position. Determining relevance of issue ------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Not all issues are relevant for Nextcloud. Bugs can be due to a specific configuration or unsupported platforms. Raspberry Pi's suffer from SQLite time-outs, nginx has problems Apache doesn't and Microsoft Server with IIS is not well supported. While external issues are not always a reason to close a report, be sure that they are clear: does the user use the 'standard' platform? Ask for information if this is missing. Last but not least, the problem might be due to the user doing something that simply does not work. Your general Nextcloud knowledge might be helpful here - if this is the case, you can often swiftly close the issue with a comment about what went wrong. @@ -93,7 +97,8 @@ Last but not least, the problem might be due to the user doing something that si .. note:: You might have to say no to some requests, for example when a problem has been solved in a new release but won't become available for the release the reporter is using; or when a solution has been chosen which the reporter is unhappy about. Be considerate. People feel surprisingly strong about Nextcloud, and you should take care to explain that we don't aim to ignore them; on the contrary. But sometimes, decisions which benefit the majority of users don't help an individual. The extensibility and open availability of the code of Nextcloud is here to relieve the pain of such decisions. Determining if the report is complete -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Now that you know that the bug report is unique, and that is not an external issue, you need to check all the needed information is there. Check `our bug reporting guidelines `_ and make sure bug reports comply with it! The information asked in the `issue template `_ is needed for developers to solve issues. @@ -103,7 +108,8 @@ Once you added a request for more information, add a #needinfo tag. If there has been a request for more information on the report, either by you, a developer or somebody else, but the original reporter (or somebody else who might have the answer) has not responded for 1 month or longer, you can close the issue. Be polite and note that whoever can answer the question can re-open the issue! Reproducing the issue ---------------------- +^^^^^^^^^^^^^^^^^^^^^ + An important step of bug triaging is trying to reproduce the bugs, this means, using the information the reporters added to the bug report to force (recreate, reproduce, repeat) the bug in the application. This is needed in order to differentiate random/race condition bugs of reproducible ones (which may be reproduced by developers too; and they can fix them). @@ -111,7 +117,8 @@ This is needed in order to differentiate random/race condition bugs of reproduci If you can't reproduce an issue in a newer version of Nextcloud, it is most likely fixed and can be closed. Comment that you failed to reproduce the problem, and if the reporter can confirm (or doesn't respond for a long time), you can close the issue. Also, be sure to add what exactly you tested with - the Nextcloud Master or a branch (and if so, when), or did you use a release, and if so - what version? Finalizing and tagging ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ + Once you are done reproducing an issue, it is time to finish up and make clear to the developers what they can do: * If it is a genuine bug (or you are pretty sure it is) add the 'bug' label. diff --git a/developer_manual/client_apis/OCS/index.rst b/developer_manual/client_apis/OCS/index.rst index 8a6c5a612..6fb6910b5 100644 --- a/developer_manual/client_apis/OCS/index.rst +++ b/developer_manual/client_apis/OCS/index.rst @@ -9,7 +9,6 @@ This document provides a quick overview of the OCS API endpoints supported in Ne All requests need to provide authentication information, either as a Basic Auth header or by passing a set of valid session cookies, if not stated otherwise. --------------------------- Testing requests with curl -------------------------- @@ -23,7 +22,6 @@ For example: you can perform a :code:`GET` request to get information about a us curl -u username:password -X GET 'https://cloud.example.com/ocs/v1.php/...' -H "OCS-APIRequest: true" -------------- User metadata ------------- @@ -66,7 +64,6 @@ This request returns the available metadata of a user. Admin users can see the i ----------------- Capabilities API ---------------- diff --git a/developer_manual/client_apis/WebDAV/index.rst b/developer_manual/client_apis/WebDAV/index.rst index b970b8157..f0bd38a6e 100644 --- a/developer_manual/client_apis/WebDAV/index.rst +++ b/developer_manual/client_apis/WebDAV/index.rst @@ -7,7 +7,6 @@ WebDAV Client API's This document provides a quick overview of the WebDAV operations supported in Nextcloud, to keep things readable it won't go into many details for each operation, further information for each operation can be found in the corresponding rfc where applicable -------------- WebDAV Basics ------------- @@ -15,7 +14,6 @@ The base url for all WebDAV operations for a Nextcloud instance is :code:`/remot All requests need to provide authentication information, either as a Basic Auth header or by passing a set of valid session cookies. --------------------------- Testing requests with curl -------------------------- @@ -39,7 +37,6 @@ For example: you can perform a :code:`PROPFIND` request to find files in a folde ' --------------------------- Listing Folders (rfc4918_) -------------------------- @@ -49,9 +46,8 @@ The contents of a folder can be listed by sending a :code:`PROPFIND` request to PROPFIND remote.php/dav/files/user/path/to/folder -~~~~~~~~~~~~~~~~~~~~~ Requesting properties -~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^ By default, a :code:`PROPFIND` request will only return a small number of properties for each file: last modified date, file size, whether it's a folder, etag and mime type. @@ -98,13 +94,11 @@ The following properties are supported: - :code:`{http://owncloud.org/ns}has-preview` - :code:`{http://owncloud.org/ns}size` Unlike :code:`getcontentlength`, this property also works for folders reporting the size of everything in the folder. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Getting properties for just the folder -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can request properties of a folder without also getting the folder contents by adding a :code:`Depth: 0` header to the request. ------------------ Downloading files ----------------- @@ -114,7 +108,6 @@ A file can be downloaded by sending a :code:`GET` request to the WebDAV url of t GET remote.php/dav/files/user/path/to/file ---------------- Uploading files --------------- @@ -126,7 +119,6 @@ A file can be uploading by sending a :code:`PUT` request to the file and sending Any existing file will be overwritten by the request. ---------------------------- Creating folders (rfc4918_) --------------------------- @@ -136,7 +128,6 @@ A folder can be created by sending a :code:`MKCOL` request to the folder. MKCOL remote.php/dav/files/user/path/to/new/folder -------------------------------------- Deleting files and folders (rfc4918_) ------------------------------------- @@ -148,7 +139,6 @@ A file or folder can be created by sending a :code:`DELETE` request to the file When deleting a folder, it's contents will be deleted recursively. ------------------------------------ Moving files and folders (rfc4918_) ----------------------------------- @@ -161,7 +151,6 @@ A file or folder can be moved by sending a :code:`MOVE` request to the file or f The overwrite behavior of the move can be controlled by setting the :code:`Overwrite` head to :code:`T` or :code:`F` to enable or disable overwriting respectively. ------------------------------------- Copying files and folders (rfc4918_) ------------------------------------ @@ -174,7 +163,6 @@ A file or folder can be copied by sending a :code:`COPY` request to the file or The overwrite behavior of the copy can be controlled by setting the :code:`Overwrite` head to :code:`T` or :code:`F` to enable or disable overwriting respectively. ------------------- Settings favorites ------------------ @@ -194,7 +182,6 @@ A file or folder can be marked as favorite by sending a :code:`PROPPATCH` reques Setting the :code:`oc:favorite` property to 1 marks a file as favorite, setting it to 0 un-marks it as favorite. ------------------ Listing favorites ----------------- diff --git a/developer_manual/client_apis/index.rst b/developer_manual/client_apis/index.rst index 5f0836bab..bb3cf41fc 100644 --- a/developer_manual/client_apis/index.rst +++ b/developer_manual/client_apis/index.rst @@ -6,7 +6,6 @@ Client API's Nextcloud provides an number of api's for client applications to talk to. ------- WebDAV ------ WebDAV is the main api for file related operations, it supports listing directories, downloading an uploading files, manipulating tags and favorites and more. @@ -14,7 +13,6 @@ WebDAV is the main api for file related operations, it supports listing director An overview of how to use the various WebDAV api's can be found at :doc:`WebDAV/index` ---- OCS --- diff --git a/developer_manual/core/configfile.rst b/developer_manual/core/configfile.rst index 8e84d8433..5980f203f 100644 --- a/developer_manual/core/configfile.rst +++ b/developer_manual/core/configfile.rst @@ -1,3 +1,4 @@ +========== App config ========== diff --git a/developer_manual/core/externalapi.rst b/developer_manual/core/externalapi.rst index 0dc72095c..598977106 100644 --- a/developer_manual/core/externalapi.rst +++ b/developer_manual/core/externalapi.rst @@ -1,3 +1,4 @@ +============ External API ============ @@ -13,7 +14,8 @@ Usage ----- Registering Methods -~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^ + Methods are registered inside the :file:`appinfo/routes.php` by returning an array holding the endpoint meta data. @@ -27,7 +29,8 @@ array holding the endpoint meta data. ]; Returning Data -~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^ + Once the API backend has matched your URL, your callable function as defined in **BarController::getFoo** will be executed. The AppFramework will make sure that send parameters are provided to the method based on its declaration. To return @@ -36,14 +39,16 @@ data back to the client, you should return an instance of (a subclass of) The API backend will then use this to construct the XML or JSON response. Authentication & Basics -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ + Because REST is stateless you have to send user and password each time you access the API. Therefore running Nextcloud **with SSL is highly recommended**; otherwise **everyone in your network can log your credentials**:: https://user:password@example.com/ocs/v1.php/apps/yourapp Output -~~~~~~ +^^^^^^ + The output defaults to XML. If you want to get JSON append this to the URL:: ?format=json @@ -85,7 +90,8 @@ Output from the application is wrapped inside a **data** element: } Statuscodes -~~~~~~~~~~~ +^^^^^^^^^^^ + The statuscode can be any of the following numbers: * **100** - successful diff --git a/developer_manual/core/ocs-share-api.rst b/developer_manual/core/ocs-share-api.rst index 19bd8e61b..7cbc903b7 100644 --- a/developer_manual/core/ocs-share-api.rst +++ b/developer_manual/core/ocs-share-api.rst @@ -10,10 +10,10 @@ The base URL for all calls to the share API is: */ocs/v2.php All calls to OCS endpoints require the ``OCS-APIRequest`` header to be set to ``true``. Local Shares -============ +------------ Get All Shares --------------- +^^^^^^^^^^^^^^ Get all shares from the user. @@ -28,7 +28,7 @@ Statuscodes: * 404 - couldn't fetch shares Get Shares from a specific file or folder ------------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get all shares from a given file/folder. @@ -50,7 +50,7 @@ Statuscodes: * 404 - file doesn't exist Get information about a known Share ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get information about a given share. @@ -67,7 +67,7 @@ Statuscodes: * 404 - share doesn't exist Create a new Share ------------------- +^^^^^^^^^^^^^^^^^^ Share a file/folder with a user/group or as public link. @@ -93,7 +93,7 @@ Statuscodes: * 404 - file couldn't be shared Delete Share ------------- +^^^^^^^^^^^^ Remove the given share. @@ -108,7 +108,7 @@ Statuscodes: * 404 - file couldn't be deleted Update Share ------------- +^^^^^^^^^^^^ Update a given share. Only one value can be updated per request. @@ -135,7 +135,7 @@ Statuscodes: Federated Cloud Shares -====================== +---------------------- Both the sending and the receiving instance need to have federated cloud sharing enabled and configured. See `Configuring Federated Cloud Sharing `_. @@ -143,7 +143,7 @@ enabled and configured. See `Configuring Federated Cloud Sharing `_ @@ -151,7 +151,7 @@ of the share recipient as shareWith. See `Create a new Share`_ for more informat List accepted Federated Cloud Shares ------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get all federated cloud shares the user has accepted. @@ -165,7 +165,7 @@ Statuscodes: * 100 - successful Get information about a known Federated Cloud Share ---------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get information about a given received federated cloud that was sent from a remote instance. @@ -182,7 +182,7 @@ Statuscodes: * 404 - share doesn't exist Delete an accepted Federated Cloud Share ----------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Locally delete a received federated cloud share that was sent from a remote instance. @@ -199,7 +199,7 @@ Statuscodes: * 404 - share doesn't exist List pending Federated Cloud Shares ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get all pending federated cloud shares the user has received. @@ -213,7 +213,7 @@ Statuscodes: * 100 - successful Accept a pending Federated Cloud Share --------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Locally accept a received federated cloud share that was sent from a remote instance. @@ -230,7 +230,7 @@ Statuscodes: * 404 - share doesn't exist Decline a pending Federated Cloud Share ---------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Locally decline a received federated cloud share that was sent from a remote instance. diff --git a/developer_manual/core/theming.rst b/developer_manual/core/theming.rst index 4b3b6678c..10c390992 100644 --- a/developer_manual/core/theming.rst +++ b/developer_manual/core/theming.rst @@ -1,3 +1,4 @@ +================= Theming Nextcloud ================= Themes can be used to customize the look and feel of Nextcloud. @@ -5,7 +6,8 @@ Themes can be used to customize the look and feel of Nextcloud. .. note:: This is an advanced way of theming Nextcloud; the Nextcloud team recommends instead the use of the :doc:`configuration_server/theming` app which, when enabled, can be accessed from the Admin settings. Getting started -=============== +--------------- + A good idea to get started with a dynamically created website is to inspect it with **web developer tools**, that are found in almost any browser. They show the generated HTML and the CSS Code that the client/browser is receiving: With this facts you can easily determine where the following object-related attributes for the phenomenons are settled: @@ -21,7 +23,8 @@ The next thing you should do, before starting any changes, is to make a backup o Creating and activating a new theme -=================================== +----------------------------------- + There are two basic ways of creating new themings: * doing all new from scratch @@ -35,7 +38,8 @@ Depending on how you created your new theme it will be necessary to: Structure -========= +--------- + The folder structure of a theme is exactly the same as the main Nextcloud structure. You can override js files, images, translations and templates with own versions. CSS files are loaded additionally to the default files so you can @@ -52,7 +56,7 @@ for example in /nextcloud/core/ and /nextcloud/settings/ in these sub folders: Notes for Updates -================= +----------------- .. note:: With Nextcloud 12, CSS files have been merged into one server.css so in order to keep your theme working you should consolidate your existing css styles into a server.css file. As for the example theme the styles.css file has been renamed to server.css. @@ -74,15 +78,18 @@ But this is unlikely and will be mentioned in the Nextcloud release notes if it How to change images and the logo -================================= +--------------------------------- + A new logo which you may want to insert can be added as follows: Figure out the path of the old logo ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Replace the old picture, which position you found out as described under 1.3. by adding an extension in case you want to re-use it later. Creating an own logo --------------------- +^^^^^^^^^^^^^^^^^^^^ + If you want to do a quick exchange like (1) it's important to know the size of the picture before you start creating an own logo: * Go to the place in the filesystem, that has been shown by the web developer tool/s @@ -94,7 +101,8 @@ The (main) pictures that can be found inside Nextcloud standard theming are the * The logo at the login-page above the credentials-box and in the header: …/nextcloud/themes/default/core/img/logo.svg Inserting your new logo ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ + Inserting a new logo into an existing theme is as simple as replacing the old logo with the new (generated) one. You can use: scalable vector graphics (.svg) or common graphics formats for the Internet such as portable network graphics (.png) or .jpeg. Just insert the new created picture by using the unchanged name of the old picture. @@ -102,7 +110,8 @@ Just insert the new created picture by using the unchanged name of the old pictu The app icons can also be overwritten in a theme. To change for example the app icon of the activity app you need to overwrite it by saving the new image to …/nextcloud/themes/default/apps/activity/img/activity.svg. Changing favicon ----------------- +^^^^^^^^^^^^^^^^ + For compatibility with older browsers, favicon (the image that appears in your browser tab) uses .../nextcloud/core/img/favicon.ico. To customize favicon for MyTheme: @@ -112,7 +121,7 @@ To customize favicon for MyTheme: * Include .../nextcloud/themes/MyTheme/core/img/favicon.svg and favicon.png to cover any future updates to favicon handling. Changing the default colours ----------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can inject custom variables into the SCSS generator to apply colors to the default css code by adding the following method to defaults.php: @@ -172,7 +181,8 @@ Save the file and refresh the browser for the changes to take effect. How to change translations -========================== +-------------------------- + .. versionadded 8.0 You can override the translation of single strings within your theme. Simply @@ -213,7 +223,7 @@ the second one is read by the PHP code and provides the data for translated terms in there. How to update custom mimetype icons -=================================== +----------------------------------- The following command is required to run after adding custom mimetype icons to your theme: @@ -223,7 +233,8 @@ The following command is required to run after adding custom mimetype icons to y How to change names, slogans and URLs -===================================== +------------------------------------- + The Nextcloud theming allows a lot of the names that are shown on the web interface to be changed. It's also possible to change the URLs to the documentation or the Android/iOS apps. This can be done with a file named ``defaults.php`` within the root of the theme. You can find it in the example theme (*/themes/example/defaults.php*). In there you need to specify a class named ``OC_Theme`` and need to implement the methods you want to overwrite: @@ -270,7 +281,8 @@ One exception is the method ``buildDocLinkToKey`` which gets passed in a key as Testing the new theme out -========================= +------------------------- + There are different options for doing so: * If you're using a tool like the Inspector tools inside Mozilla, you can test out the CSS-Styles immediately inside the css-attributes, while looking at them. diff --git a/developer_manual/core/translation.rst b/developer_manual/core/translation.rst index e389f3d8b..ee83e7df4 100644 --- a/developer_manual/core/translation.rst +++ b/developer_manual/core/translation.rst @@ -1,3 +1,4 @@ +=========== Translation =========== @@ -16,19 +17,19 @@ You shall never split sentences! -------------------------------- Reason: -~~~~~~~ +^^^^^^^ Translators lose the context and they have no chance to possibly re-arrange words. Example: -~~~~~~~~ +^^^^^^^^ .. code-block:: php t('Select file from')) . ' '; ?>t('local filesystem'));?>t(' or ')); ?>t('cloud'));?> Translators will translate: -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Select file from * local filesystem @@ -38,12 +39,12 @@ Translators will translate: Translating these individual strings results in ``local filesystem`` and ``cloud`` losing case. The two white spaces surrounding ``or`` will get lost while translating as well. For languages that have a different grammatical order it prevents the translators from reordering the sentence components. HTML on translation string: -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^ HTML tags in translation strings is ugly but usually translators can handle this. What about variable in the strings? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you need to add variables to the translation strings do it like this: @@ -63,7 +64,7 @@ Multiple nightly jobs have been setup in order to synchronize translations - it' #. Finally the changes are pushed to Git. Please follow the steps below to add translation support to your app: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Create a folder ``l10n``. #. Create the file ``ignorelist`` which can contain files which shall not be scanned during step 4. diff --git a/developer_manual/core/unit-testing.rst b/developer_manual/core/unit-testing.rst index 3c5405f77..25f70833a 100644 --- a/developer_manual/core/unit-testing.rst +++ b/developer_manual/core/unit-testing.rst @@ -1,3 +1,4 @@ +============ Unit-Testing ============ @@ -5,7 +6,7 @@ PHP unit testing ---------------- Getting PHPUnit -~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^ Nextcloud uses PHPUnit >= 4.8 for unit testing. @@ -30,7 +31,7 @@ And you can update it using:: You can find more information in the PHPUnit documentation: https://phpunit.de/manual/current/en/installation.html Writing PHP unit tests -~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^ To get started, do the following: - Create a directory called ``tests`` in the top level of your application @@ -92,7 +93,7 @@ so the next test can run without side effects, like remaining files and entries For more resources on PHPUnit visit: http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html Bootstrapping Nextcloud -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ If you use Nextcloud functions or classes in your code, you'll need to make them available to your test by bootstrapping Nextcloud. To do this, you'll need to provide the ``--bootstrap`` argument when running PHPUnit: @@ -115,7 +116,7 @@ adjust your php.ini and file rights. su -c "chmod a+w data/nextcloud.log" Running unit tests for the Nextcloud core project -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The core project provides a script that runs all the core unit tests using different database backends like sqlite, mysql, pgsql, oci (for Oracle):: ./autotest.sh @@ -129,7 +130,7 @@ To run a specific test suite (note that the test file path is relative to the "t ./autotest.sh sqlite lib/share/share.php Further Reading -~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^ - http://googletesting.blogspot.de/2008/08/by-miko-hevery-so-you-decided-to.html - http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html - http://www.youtube.com/watch?v=4E4672CS58Q&feature=bf_prev&list=PLBDAB2BA83BB6588E @@ -141,7 +142,7 @@ JavaScript unit testing for core JavaScript Unit testing for **core** and **core apps** is done using the `Karma `_ test runner with `Jasmine `_. Installing Node JS -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ To run the JavaScript unit tests you will need to install **Node JS**. @@ -151,7 +152,7 @@ After that you will need to setup the **Karma** test environment. The easiest way to do this is to run the automatic test script first, see next section. Running all tests -~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^ To run all tests, just run:: @@ -160,7 +161,7 @@ To run all tests, just run:: This will also automatically set up your test environment. Debugging tests in the browser -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To debug tests in the browser, you need to run **Karma** in browser mode:: @@ -175,14 +176,14 @@ An empty page will appear, from which you must open the browser console (F12 in Every time you reload the page, the unit tests will be relaunched and will output the results in the browser console. Unit test paths -~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^ JavaScript unit test examples can be found in :file:`apps/files/tests/js/`. Unit tests for the core app JavaScript code can be found in :file:`core/js/tests/specs`. Documentation -~~~~~~~~~~~~~ +^^^^^^^^^^^^^ Here are some useful links about how to write unit tests with Jasmine and Sinon: diff --git a/developer_manual/design/content.rst b/developer_manual/design/content.rst index 7b9cfadd0..40fb9d125 100644 --- a/developer_manual/design/content.rst +++ b/developer_manual/design/content.rst @@ -2,6 +2,6 @@ .. codeauthor:: John Molakvoæ .. _content: -=============== +============ Main content -=============== +============ diff --git a/developer_manual/design/html.rst b/developer_manual/design/html.rst index df8f26d51..29d81bea4 100644 --- a/developer_manual/design/html.rst +++ b/developer_manual/design/html.rst @@ -2,12 +2,12 @@ .. codeauthor:: John Molakvoæ .. _html: -=============== +============= Html elements -=============== +============= Progress bar -============= +------------ Nextcloud support and provides an already themed progress bar. @@ -24,7 +24,7 @@ Please use the html5 ``progress`` element. .. _checkboxes-and-radios: Checkboxes and radios -====================== +--------------------- As default html5 checkboxes & radios are **not** customizable, we created an override using label and ``::after`` elements. @@ -76,4 +76,4 @@ Requirements: Buttons -================== +------- diff --git a/developer_manual/design/icons.rst b/developer_manual/design/icons.rst index a461dc9f6..430c73704 100644 --- a/developer_manual/design/icons.rst +++ b/developer_manual/design/icons.rst @@ -2,9 +2,9 @@ .. codeauthor:: John Molakvoæ .. _icons: -======== +===== Icons -======== +===== White icons only have a grey background on this documentation page for readability purposes. diff --git a/developer_manual/design/navigation.rst b/developer_manual/design/navigation.rst index ed9d0428f..335f4998a 100644 --- a/developer_manual/design/navigation.rst +++ b/developer_manual/design/navigation.rst @@ -7,7 +7,7 @@ App Navigation =============== Introduction -============= +------------ The main navigation menu represents the main navigation of your app. @@ -22,7 +22,7 @@ We implemented various essential functions and provide easy way of using them. Basic layout -============= +------------ .. figure:: ../images/navigation.png :alt: Navigation screenshot @@ -45,14 +45,14 @@ Basic layout Basic rules -============= +----------- * You can **not** change the default padding of the navigation elements. * We encourage you to add icons on every top-level item of your navigation for accessibility. * Do **not** override the default structure and/or CSS. Everything has been carefully tuned. Utils: menu, counter & buttons -=============================== +------------------------------ Each entry is allowed to have a counter and/or a button for user interaction. @@ -77,7 +77,7 @@ Each entry is allowed to have a counter and/or a button for user interaction. .. _navigation_menu: Menu -^^^^^^ +^^^^ If you need to add a few interactions for your entry, you can put everything in a popover menu. The menu needs to be placed after the ``app-navigation-entry-utils``. @@ -150,7 +150,7 @@ In case of AngularJS the following small directive can be added to handle all th .. _navigation_counter: Counter -^^^^^^^^ +^^^^^^^ If you need to add a counter to your menu entry, you can simply use this structure. Do not change the alignment of the text. If you're using @@ -186,7 +186,7 @@ Use it like this: .. _navigation_buttons: Buttons -^^^^^^^^^ +^^^^^^^ The same way we display the menu three-dot-icon button, you're allowed to use up to 2 buttons in a single entry. @@ -211,7 +211,8 @@ The same way we display the menu three-dot-icon button, you're allowed to use up Drag and drop -============== +------------- + The class which should be applied to a first level element **li** that hosts or can host a second level is **drag-and-drop**. This will cause the hovered entry to slide down giving a visual hint that it can accept the dragged element. In case of jQuery UI's droppable feature, the **hoverClass** option should be set to the **drag-and-drop** class. @@ -232,7 +233,7 @@ In case of jQuery UI's droppable feature, the **hoverClass** option should be se Collapsible entry -================== +----------------- By default, all sub-entries are shown. This behavior can be changed by creating a collapsible menu. @@ -272,7 +273,7 @@ The opening of the menu is activated and animated by the class ``open`` on the m Entry bullet -============= +------------ Every entry can have a colored marker in front of it. We call it a `bullet`. @@ -292,7 +293,7 @@ We call it a `bullet`. Undo entry -=========== +---------- * Undo entries can be used on any level you want. * When an entry is deleted, please use the usual **7 seconds delay feedback** before final deletion. @@ -321,7 +322,7 @@ Undo entry Edit entry -=========== +---------- * Editable entries can be used on any level you want. * You can replace the ``form`` by a ``div`` if you wish to do your request with JS. @@ -354,7 +355,7 @@ Edit entry Pinned entry -============= +------------ Every top-level entry can be `pinned` at the bottom. @@ -381,8 +382,8 @@ Every top-level entry can be `pinned` at the bottom.
  • Pinned entry
  • -Various informations -===================== +Various information +------------------- * You can add the ``icon-loading-small`` class to any ``li`` element to set it in a `loading` state. * Every element as a ``min-height`` of 44px as that is the minimum recommended touch target. It also helps with clickability and separation on desktop environments. diff --git a/developer_manual/design/popovermenu.rst b/developer_manual/design/popovermenu.rst index fd47b8855..0bbe60e9f 100644 --- a/developer_manual/design/popovermenu.rst +++ b/developer_manual/design/popovermenu.rst @@ -2,19 +2,19 @@ .. codeauthor:: John Molakvoæ .. _popovermenu: -=============== +============ Popover Menu -=============== +============ What is a popover menu -======================= +---------------------- This is a quick menu that open on click. For menus, we use the three-dot-icon. This is exactly the same as the :ref:`navigation menu `. The only difference is the popovermenu class. Basic layout -============= +------------ .. figure:: ../images/popovermenu.png :alt: Popover image example @@ -62,7 +62,7 @@ Basic layout Technical details -================== +----------------- * The only allowed menu items elements are **a**, **button** and **span** for the checkbox and radio only. * You can mix between a and button on the same menu (in case of form or direct link) like the example above @@ -78,7 +78,8 @@ Technical details .. image:: ../images/popover-position.png Alignment -========== +--------- + If you want to align your menu, you can add the class to the main popovermenu div. * Center: ``menu-center`` diff --git a/developer_manual/design/settings.rst b/developer_manual/design/settings.rst index a2d676b74..9d712f1b5 100644 --- a/developer_manual/design/settings.rst +++ b/developer_manual/design/settings.rst @@ -2,9 +2,9 @@ .. codeauthor:: John Molakvoæ .. _settings: -=============== +======== Settings -=============== +======== To create a settings area create a div with the id ``app-settings`` inside the ``app-navigation`` div. diff --git a/developer_manual/general/backporting.rst b/developer_manual/general/backporting.rst index aca39f855..fe316ee8f 100644 --- a/developer_manual/general/backporting.rst +++ b/developer_manual/general/backporting.rst @@ -1,3 +1,4 @@ +=========== Backporting =========== diff --git a/developer_manual/general/code-of-conduct.rst b/developer_manual/general/code-of-conduct.rst index 27a5a6acf..6556caaf3 100644 --- a/developer_manual/general/code-of-conduct.rst +++ b/developer_manual/general/code-of-conduct.rst @@ -1,3 +1,4 @@ +========================= Community Code of Conduct ========================= diff --git a/developer_manual/general/codingguidelines.rst b/developer_manual/general/codingguidelines.rst index a0f2632fb..05db1937b 100644 --- a/developer_manual/general/codingguidelines.rst +++ b/developer_manual/general/codingguidelines.rst @@ -1,3 +1,4 @@ +================================= Coding Style & General Guidelines ================================= @@ -18,6 +19,7 @@ General Labels ------ + We assign labels to issues and pull requests to make it easy to find them and to signal what needs to be done. Some of these are assigned by the developers, others by QA, bug triagers, project lead or maintainers and so on. It is not desired that users/reporters of bugs assign labels themselves, unless they are developers/contributors to Nextcloud. The most important labels and their meaning: @@ -42,6 +44,7 @@ If you want a label not in the list above, please first discuss on the mailing l Coding ------ + * Maximum line-length of 80 characters * Use tabs to indent * A tab is 4 spaces wide @@ -86,6 +89,7 @@ If you edit an existing file please add a copyright notice with your name, if yo User interface -------------- + * Software should get out of the way. Do things automatically instead of offering configuration options. * Software should be easy to use. Show only the most important elements. Secondary elements only on hover or via Advanced function. * User data is sacred. Provide undo instead of asking for confirmation - `which might be dismissed `_ @@ -97,6 +101,7 @@ User interface PHP --- + The Nextcloud coding style guide is based on `PEAR Coding Standards `_. Always use:: @@ -131,6 +136,7 @@ All API methods need to be marked with `PHPDoc `_ without the whitespace rules. * Use a :file:`js/main.js` or :file:`js/app.js` where your program is started @@ -292,6 +302,7 @@ In general take a look at `JSLint `_ without the whitespa Objects & Inheritance ^^^^^^^^^^^^^^^^^^^^^ + Try to use OOP in your JavaScript to make your code reusable and flexible. This is how you'd do inheritance in JavaScript: @@ -332,6 +343,7 @@ This is how you'd do inheritance in JavaScript: Objects, Functions & Variables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Use *UpperCamelCase* for Objects, *lowerCamelCase* for functions and variables. .. code-block:: javascript @@ -353,6 +365,7 @@ Use *UpperCamelCase* for Objects, *lowerCamelCase* for functions and variables. Operators ^^^^^^^^^ + Use **===** and **!==** instead of **==** and **!=**. Here's why: @@ -374,6 +387,7 @@ Here's why: Control Structures ^^^^^^^^^^^^^^^^^^ + * Always use { } for one line ifs * Split long ifs into multiple lines * Always use break in switch statements and prevent a default block with warnings if it shouldn't be accessed @@ -417,6 +431,7 @@ Control Structures CSS --- + Take a look at the `Writing Tactical CSS & HTML `_ video on YouTube. Don't bind your CSS too much to your HTML structure and try to avoid IDs. Also try to make your CSS reusable by grouping common attributes into classes. diff --git a/developer_manual/general/debugging.rst b/developer_manual/general/debugging.rst index 83f376b4f..d3c727bc7 100644 --- a/developer_manual/general/debugging.rst +++ b/developer_manual/general/debugging.rst @@ -1,3 +1,4 @@ +========= Debugging ========= @@ -70,7 +71,7 @@ Once you are familiar with how your debugging client works, you can start debugg For debugging scripts on the command line, like ``occ`` or unit tests, set the ``XDEBUG_CONFIG`` environment variable. -Debugging Javascript +Debugging JavaScript -------------------- By default all Javascript files in Nextcloud are minified (compressed) into a single file without whitespace. To prevent this, see Debug mode. diff --git a/developer_manual/general/devenv.rst b/developer_manual/general/devenv.rst index 05790b0c6..75b8ef88a 100644 --- a/developer_manual/general/devenv.rst +++ b/developer_manual/general/devenv.rst @@ -9,14 +9,14 @@ Development Environment Please follow the steps on this page to set up your development environment. Set up Web server and database -============================== +------------------------------ First `set up your Web server and database `_ (**Section**: Manual Installation - Prerequisites). .. TODO ON RELEASE: Update version number above on release Get the source -============== +-------------- There are two ways to obtain Nextcloud sources: @@ -28,7 +28,7 @@ There are two ways to obtain Nextcloud sources: To check out the source from `GitHub`_ you will need to install Git (see `Setting up Git `_ from the GitHub help) Gather information about server setup -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To get started the basic Git repositories need to cloned into the Web server's directory. Depending on the distribution this will either be @@ -45,7 +45,7 @@ Then identify the user and group the Web server is running as and the Apache use * **wwwrun** Check out the code ------------------- +^^^^^^^^^^^^^^^^^^ The following commands are using **/var/www** as the Web server's directory and **www-data** as user name and group. @@ -78,7 +78,8 @@ or:: After the clone Open http://localhost/core (or the corresponding URL) in your web browser to set up your instance. Enabling debug mode -------------------- +^^^^^^^^^^^^^^^^^^^ + .. _debugmode: .. note:: Do not enable this for production! This can create security problems and is only meant for debugging and development! @@ -92,7 +93,7 @@ To disable JavaScript and CSS caching debugging has to be enabled by setting ``d ); Keep the code up-to-date ------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^ If you have more than one repository cloned, it can be time consuming to do the same the action to all repositories one by one. To solve this, you can use the following command template:: diff --git a/developer_manual/general/performance.rst b/developer_manual/general/performance.rst index 0fbd5a309..174524d77 100644 --- a/developer_manual/general/performance.rst +++ b/developer_manual/general/performance.rst @@ -1,3 +1,4 @@ +========================== Performance Considerations ========================== @@ -9,6 +10,7 @@ This document introduces some common considerations and tips on improving perfor Database performance -------------------- + The database plays an important role in Nextcloud performance. The general rule is: database queries are very bad and should be avoided if possible. The reasons for that are: * Roundtrips: Bigger Nextcloud installations have the database not installed on the application server but on a remote dedicated database server. The problem is that database queries then go over the network. These roundtrips can add up significantly if you have a lot of queries. @@ -53,7 +55,7 @@ If you increase the long_query_time to 100 and add log-queries-not-using-indexes long_query_time=100 Measuring performance -~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^ If you do bigger changes in the architecture or the database structure you should always double check the positive or negative performance impact. There are a `few nice small scripts `_ that can be used for this. @@ -61,4 +63,5 @@ The recommendation is to automatically do 10000 PROPFINDs or file uploads, measu Getting help ------------ + If you need help with performance or other issues please ask on our `forums `_ or on our IRC channel **#nextcloud-dev** on **irc.freenode.net**. diff --git a/developer_manual/general/security.rst b/developer_manual/general/security.rst index f3139c6a0..2ba3a5ee9 100644 --- a/developer_manual/general/security.rst +++ b/developer_manual/general/security.rst @@ -1,3 +1,4 @@ +=================== Security Guidelines =================== @@ -11,6 +12,7 @@ This guideline highlights some of the most common security problems and how to p SQL Injection ------------- + `SQL Injection `_ occurs when SQL query strings are concatenated with variables. To prevent this, always use prepared queries: @@ -43,7 +45,7 @@ Despite the fact that Nextcloud uses Content-Security-Policy to prevent the exec To prevent XSS in your app you have to sanitize the templates and all JavaScripts which performs a DOM manipulation. Templates -~~~~~~~~~ +^^^^^^^^^ Let's assume you use the following example in your application: @@ -68,7 +70,7 @@ To prevent XSS in your app, **never use echo, print() or <\%=** - use **p()** in .. note:: Should you ever require to print something unescaped, double check if it is really needed. If there is no other way (e.g. when including of subtemplates) use `print_unescaped` with care. JavaScript -~~~~~~~~~~ +^^^^^^^^^^ Avoid manipulating the HTML directly via JavaScript, this often leads to XSS since people often forget to sanitize variables: @@ -109,6 +111,7 @@ This is already built into Nextcloud if :php:class:`OC_Template`. Code executions / File inclusions --------------------------------- + Code Execution means that an attacker is able to include an arbitrary PHP file. This PHP file runs with all the privileges granted to the normal application and can do an enormous amount of damage. Code executions and file inclusions can be easily prevented by **never** allowing user-input to run through the following functions: @@ -132,6 +135,7 @@ Code executions and file inclusions can be easily prevented by **never** allowin Directory Traversal ------------------- + Very often developers forget about sanitizing the file path (removing all \\ and /), this allows an attacker to traverse through directories on the server which opens several potential attack vendors including privilege escalations, code executions or file disclosures. **DON'T** @@ -211,6 +215,7 @@ Always store user data or configuration files in safe locations, e.g. **nextclou Cross site request forgery -------------------------- + Using `CSRF `_ one can trick a user into executing a request that he did not want to make. Thus every POST and GET request needs to be protected against it. The only places where no CSRF checks are needed are in the main template, which is rendering the application, or in externally callable interfaces. .. note:: Submitting a form is also a POST/GET request! @@ -226,6 +231,7 @@ If you are using the App Framework, every controller method is automatically che Unvalidated redirects --------------------- + This is more of an annoyance than a critical security vulnerability since it may be used for social engineering or phishing. Always validate the URL before redirecting if the requested URL is on the same domain or an allowed resource. @@ -246,4 +252,5 @@ Always validate the URL before redirecting if the requested URL is on the same d Getting help ------------ + If you need help to ensure that a function is secure please ask on our `forum `_ or on our IRC channel **#nextcloud-dev** on **irc.freenode.net**. diff --git a/developer_manual/index.rst b/developer_manual/index.rst index f300334ee..7ac456cdd 100644 --- a/developer_manual/index.rst +++ b/developer_manual/index.rst @@ -9,7 +9,7 @@ Nextcloud Developer Documentation .. _Documentation: https://github.com/nextcloud/documentation#nextcloud-documentation Table of Contents -================= +----------------- .. toctree:: :maxdepth: 2 diff --git a/user_manual/pim/sync_ios.rst b/user_manual/pim/sync_ios.rst index bea4a89ca..b7a7e8131 100644 --- a/user_manual/pim/sync_ios.rst +++ b/user_manual/pim/sync_ios.rst @@ -1,3 +1,4 @@ +============================= iOS - Synchronize iPhone/iPad ============================= diff --git a/user_manual/pim/sync_osx.rst b/user_manual/pim/sync_osx.rst index 6f8cf4aea..003b52816 100644 --- a/user_manual/pim/sync_osx.rst +++ b/user_manual/pim/sync_osx.rst @@ -1,3 +1,4 @@ +======================= Synchronizing with OS X ======================= diff --git a/user_manual/pim/sync_thunderbird.rst b/user_manual/pim/sync_thunderbird.rst index 96cc30210..6cec07ab2 100644 --- a/user_manual/pim/sync_thunderbird.rst +++ b/user_manual/pim/sync_thunderbird.rst @@ -1,5 +1,6 @@ +================================================== Thunderbird - Synchronize Addressbook and Calendar -===================================== +================================================== Addressbook ----------- @@ -41,7 +42,7 @@ You'll see your address book populate from Nextcloud! The rest of the details of dealing with Thunderbird CardBook are left to the reader... Calendar ------------ +-------- - `Thunderbird `_ for your OS unless it comes with your OS distribution (Linux) - `Lightning `_ (a Thunderbird calendar add-on.) diff --git a/user_manual/session_management.rst b/user_manual/session_management.rst index 9ab56b9f3..144c67596 100644 --- a/user_manual/session_management.rst +++ b/user_manual/session_management.rst @@ -6,7 +6,8 @@ The personal settings page allows you to have an overview on the connected browsers and devices. Managing Connected Browsers -=========================== +--------------------------- + In the list of connected browsers you see which browsers connected to your account recently: @@ -16,7 +17,8 @@ account recently: You can use the trash icon to disconnect any of the browsers in the list. Managing Devices -================ +---------------- + In the list of connected devices you see all the devices and clients you generated a device password for and their last activity: diff --git a/user_manual/user_2fa.rst b/user_manual/user_2fa.rst index f13d11dda..6d74b91d7 100644 --- a/user_manual/user_2fa.rst +++ b/user_manual/user_2fa.rst @@ -16,7 +16,8 @@ you can enable and configure it in :doc:`userpreferences`. Below you can see how. Configuring two-factor authentication -===================================== +------------------------------------- + In your Personal Settings look up the Second-factor Auth setting. In this example this is TOTP, a Google Authenticator compatible time based code. @@ -29,7 +30,8 @@ code or scan the QR and your device will show a login code which changes every 30 seconds. Recovery codes in case you lost your 2nd factor -=============================================== +----------------------------------------------- + You should always generate backup codes for 2FA. If your 2nd factor device gets stolen or is not working, you will be able to use one of these codes to unlock your account. It effectively functions as a backup 2nd factor. To @@ -50,7 +52,8 @@ if you lose one, you still have the other. Keeping them at home is probably the best thing to do. Logging in with two-factor authentication -========================================= +----------------------------------------- + After you have logged out and need to log in again, you will see a request to enter the TOTP code in your browser. Just enter your code: @@ -64,7 +67,8 @@ If the code was correct you will be redirected to your Nextcloud account. won’t be a problem. Using client applications with two-factor authentication -======================================================== +-------------------------------------------------------- + Once you have enabled 2FA, your clients will no longer be able to connect with just your password unless they also have support for two-factor authentication. To solve this, you should generate device specific passwords for them. See