.. Netfiles API documentation master file, created by
   sphinx-quickstart on Fri Mar  6 11:42:21 2020.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Prerequisites
=============

In order for you to be able to use this API, you need to have:

API-Key
  The API-Key is a secret provided by Netfiles GmbH for your use in your application. Please note
  that the key is assigned on a per-application basis. In all examples, the placeholder for the
  API-Key is ``<myAPIKey>``

DeviceID
  This is the Unique Device ID that you must provide for each machine (Laptop, Desktop, Tablet, Phone)
  your application is installed on. It must be unique (on iOS, e.g., the best way to generate that
  ID is using ``UIDevice.current.identifierForVendor?.uuidString`` expression in *Swift*).
  We will be using ``<currentDeviceID>`` as placeholder in the examples below.

Username & User-Password
  This is the user's name (login or e-mail address) and password. We will be using ``<username>`` and ``<password>`` for this.


Authorization
-------------

Netfiles uses *Basic* authorization (also known maybe as ``HTTP-Authorization``) for user-login. This may seem insecure but since
it is always used **only with https** it shouldn't be any problem.


Basics
------

All Netfiles API requests consist of the following components:

::

    <Base-URL><Object-Path>;internal&action=mobile.json<API-Key><Device ID><Requested Method>

Base-URL
  This is the base-URL for the server. Usually, this is ``https://app.netfiles.de/``

Object-Path
  This is the path of the object that you are requesting. Usually, this is just the ``HW Object ID``.

``internal&action=mobile.json``
  This component is fixed and needs to be included as shown.

API-Key
  This is the API-Key. It is expressed as ``&apikey=<myAPIKey>``

Device ID
  The Unique DeviceID as explained above and expressed as ``&deviceID=<currentDeviceID>``

Requested Method
  This the actual function that you are requesting. It is expressed as ``&method=<requestedMethod>``. See :doc:`Calls Overview <calls/overview>` for all available request methods that you can send.

The complete Request thus looks like

::

  GET https://app.netfiles.de/<dataroom>/projectfiles/<path>;internal&action=mobile.json&apikey=anApiKey&deviceID=aDeviceID&method=getChildren

The complete request must contain the full Authorization information and the ``Accept``-Header:

::

  GET https://app.netfiles.de/;internal&action=json&apikey=<myAPIKey>&deviceID=<currentDeviceID>&method=checkIdentity
  Authorization: Basic BASE64(UTF8Bytes(<username>:<password>))
  Accept: application/json

**Note**: According to how it is implemented in the original iPad-App, the ``Authorization`` - Header must be provided with each call.

User Agent
----------

It is good practice to provide a ``User-Agent`` header. In our case, we are using ``iPad``.

Cookies
-------

With the initial ``checkIdentity`` call you will receive a set of cookies using the ``Set-Cookie``-Header. **You must keep these cookies and send them back with each request from then on.**

Only a ``checkIdentity``-call may not contain these cookies. Next time you make a ``checkIdentity``-call you need to discard the cookies before making the call.

An example of a complete call requesting the list of children of an (given you have the right api-keys) may look like this:

::

  GET https://app.netfiles.de/<dataroom>/projectfiles/<path/to/object>;internal&action=mobile.json&apikey=<myAPIKey>&&deviceID=<currentDeviceID>&method=getChildren
  Authorization: Basic BASE64(<username>:<password>)
  Accept: application/json
  netfiles: <value of the netfiles cookie>
  sk1: <value of the sk1 cookie>
  HW_User: <value of the HW_User cookie>
  HyperwaveSession: <value of the HyperwaveSession cookie>
  sk_s_web_S: <value of the sk_s_web_S cookie>
  sk_p_web_S: <value of the sk_p_web_S cookie>

Response Headers
----------------

Unfortunately, the ``Content-Type`` in the response headers from the server is always ``application/json``, even
as response to a :doc:`Get Content <calls/getcontent>` call when the content you receive is something completely
different.

You have to retrieve the object's Hyperwave Record (``getObject`` on the object or ``getChildren`` on the parent) and
check the ``documentType`` there.

On that matter, a ``.json``-file is not identified as ``application/json`` but rather ``application/octet-stream``.

So, the guideline is: trust only the ``documentType`` in the object's Hyperwave Record (retrieved either
through a call to :doc:`Get Object <calls/getobject>` or through :doc:`Get Children <calls/getchildren>` of
the appropriate parent object) *unless*:

1. The object is a file (``type`` == ``"document"``) *and*
2. Its extension is ``.json``

In this case, you should ignore what is stored in the object-record and assume it is a JSON-file.

