Compare commits

...

10 Commits

6 changed files with 577 additions and 0 deletions

View File

@ -1,2 +1,33 @@
Admin API
=========
The administration API ``/admin`` helps the administrator user manage the Sachet server.
An important component that is not within this endpoint is user management.
See :ref:`user_info_api` and :ref:`user_list_api` for information about managing users.
Server settings
---------------
Sachet has a server settings API::
GET /admin/settings
PATCH /admin/settings
PUT /admin/settings
Currently, server settings are represented by the following object:
.. code-block:: json
{
"default_permissions": ["PERMISSION1", "PERMISSION2"]
}
Anonymous permissions
^^^^^^^^^^^^^^^^^^^^^
Anonymous permissions (``default_permissions`` in the schema) are given to clients that do not authenticate.
It is an array of strings as described by :ref:`permissions_table`.
This can be useful, for example, to publish a file to the Internet.
If the Read shares permission is enabled in anonymous permissions, anyone can read a share if given the link to it.

View File

@ -1,2 +1,295 @@
Files API
=========
Overview
--------
The file upload process essentially works as follows:
#. ``POST /files`` with the metadata to create a share.
This will return an URL with the share you just created.
(See :ref:`files_list_api`.)
#. ``POST /files/<uuid>/content`` (the UUID is in the URL from the previous step) to upload the actual data of the share. (See :ref:`files_content_api`.)
#. ``GET /files/<uuid>/content`` to read the share.
Share modification is done with ``PUT /files/<uuid>/content``.
Shares can be locked, which means they can't be modified or deleted.
See :ref:`files_lock_api` for more information.
.. note::
All data uploads are chunked: see :ref:`files_chunked_upload`.
.. _files_schema:
File Schema
-----------
In JSON, a file share has the following properties::
{
"file_name": "file.txt",
"initialized": true,
"locked": false,
"owner_name": "user",
"share_id": "9ae90f06-a751-409c-a9fe-8277575b9914"
}
.. list-table::
:header-rows: 1
:widths: 25 25 25 50
* - Property
- Type
- Limits
- Description
* - ``file_name``
- String
-
- The file's name (with extension).
* - ``initialized``
- Boolean
- Read-only
- Shows if content exists for this share.
* - ``locked``
- Boolean
- Read-only
- Shows if share is locked (see :ref:`files_lock_api`.)
* - ``owner_name``
- string
-
- Username of the owner.
* - ``share_id``
- string
- Read-only
- UUID that uniquely identifies this share.
.. _files_metadata_api:
Metadata API
------------
The File Metadata API allows managing file shares' metadata.
Sachet implements the following endpoints for this API::
GET /files/<file_uuid>
PATCH /files/<file_uuid>
PUT /files/<file_uuid>
GET
^^^
Requesting ``GET /files/<file_uuid>`` returns a JSON object conforming to the :ref:`File schema<files_schema>`.
This contains the information about the share with the specified UUID.
An example response:
.. code-block:: json
{
"file_name": "file.txt",
"initialized": true,
"locked": false,
"owner_name": "user",
"share_id": "9ae90f06-a751-409c-a9fe-8277575b9914"
}
This method requires the :ref:`read<permissions_table>` permission.
PATCH
^^^^^
Requesting ``PATCH /files/<file_uuid>`` allows modifying some or all fields of the share's metadata.
The request body is JSON conforming to the :ref:`File schema<files_schema>`.
Properties may be left out: they won't be modified.
For example, to modify a share's filename:
.. code-block:: json
{
"file_name": "foobar.mp3"
}
This method requires the :ref:`modify<permissions_table>` permission.
PUT
^^^
Requesting ``PUT /files/<file_uuid>`` completely replaces a share's metadata.
The request body is JSON conforming to the :ref:`File schema<files_schema>`.
No property may be left out.
For example:
.. code-block:: json
{
"file_name": "foobar.mp4",
"owner_name": "user"
}
.. note::
The permissions from the schema that are missing here are read-only.
.. _files_list_api:
List API
--------
The File List API allows listing shares and creating new ones::
GET /files
POST /files
GET
^^^
``GET /files`` is a :ref:`paginated endpoint<pagination>` that returns a list of shares.
To access this endpoint, a user needs the :ref:`list shares<permissions_table>` permission.
POST
^^^^
``POST /files`` creates a new share.
The request body must conform to the :ref:`File schema<files_schema>`.
To access this endpoint, a user needs the :ref:`create shares<permissions_table>` permission.
.. note::
The share created here is empty, and only contains metadata.
See :ref:`files_content_api` for information on uploading content.
Upon success, the server will respond like this:
.. code-block:: json
{
"status": "success",
"url": "/files/d9eafb5e-af48-40ec-b6fd-f7ea99e6d990"
}
The ``url`` field represents the share you just created.
It can be used in further requests to upload content to the share.
.. _files_content_api:
Content API
-----------
The File Content API allows managing file shares' contents.
Sachet implements the following endpoints for this API::
POST /files/<file_uuid>/content
PUT /files/<file_uuid>/content
GET /files/<file_uuid>/content
POST
^^^^
``POST /files/<file_uuid>/content`` initializes the content of an empty share.
This endpoint requires the :ref:`create shares<permissions_table>` permission.
.. note::
You must first create a share before initializing it: see :ref:`files_list_api` for information about creation.
Uploads must be chunked (see :ref:`files_chunked_upload`).
To modify the contents of an existing share, use ``PUT`` instead.
PUT
^^^^
``PUT /files/<file_uuid>/content`` modifies the content of an existing share.
This endpoint requires the :ref:`modify shares<permissions_table>` permission.
.. note::
You must initialize a share's content using ``POST`` before modifying it.
Uploads must be chunked (see :ref:`files_chunked_upload`).
GET
^^^^
``GET /files/<file_uuid>/content`` reads the contents of a share.
This endpoint requires the :ref:`read shares<permissions_table>` permission.
This endpoint supports `HTTP Range <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range>`_ headers.
.. _files_chunked_upload :
Chunked upload protocol
^^^^^^^^^^^^^^^^^^^^^^^
To allow for uploading large files reliably, Sachet requires that you upload files in chunks.
Partial uploads do not affect the state of the share;
a new file exists only once all chunks are uploaded.
Chunks are ordered by their index.
Once an upload finishes, they are combined in that order to form the new file.
The server will respond with ``200 OK`` when chunks are sent.
When the final chunk is sent, and the upload is completed,
the server will instead respond with ``201 Created``.
Every chunk has the following schema:
.. _files_chunk_schema:
.. code-block::
dztotalchunks = 3
dzchunkindex = 2
dzuuid = "unique_id"
upload = <binary data>
.. note::
This data is sent via a ``multipart/form-data`` request; it's not JSON.
.. list-table::
:header-rows: 1
:widths: 25 25 50
* - Property
- Type
- Description
* - ``dztotalchunks``
- Integer
- Total number of chunks the client will send.
* - ``dzchunkindex``
- Integer
- Number of the chunk being sent.
* - ``dzuuid``
- String
- ID which is the same for all chunks in a single upload.
* - ``upload``
- Binary data (file)
- Data contained in this chunk.
.. _files_lock_api:
Lock API
--------
Files can be locked and unlocked.
When locked, a share can not be modified or deleted.
.. note::
When attempting illegal actions on a locked share, the server will respond ``423 Locked``.
The following API is used::
POST /files/<uuid>/lock
POST /files/<uuid>/unlock
A user needs the :ref:`lock permission<permissions_table>` to access this API.
To query whether a file is locked or not, see :ref:`files_metadata_api`.

View File

@ -11,6 +11,7 @@ Welcome to Sachet's documentation!
:caption: Contents:
authentication
pagination
permissions
user
admin

54
docs/pagination.rst Normal file
View File

@ -0,0 +1,54 @@
.. _pagination:
Paginated APIs
==============
Some APIs in Sachet might return lots of data.
Because this is often a lot to handle, Sachet will use pagination on some endpoints.
For example, let's say we want to list all shares on the server.
To do this, we'll run ``GET /files`` using the following request body:
.. code-block:: json
{
"page": "1",
"per_page": "3"
}
As seen in the above example, paginated APIs on Sachet require the following parameters:
* ``page`` : the number of the page we want to query;
* ``per_page`` : the number of items per page we receive.
For our example, the server might respond like this (fields removed for brevity):
.. code-block:: json
{
"data": [
{
"file_name": "file1",
"share_id": "339ce639-cf54-4acf-9620-c915c5dce406"
},
{
"file_name": "file2",
"share_id": "9ae90f06-a751-409c-a9fe-8277575b9914"
},
{
"file_name": "file3",
"share_id": "4f8e41ab-3327-4fc1-a52b-8951ac5c641f"
}
],
"next": 2,
"prev": null
}
Our query's result is returned as an array in ``data``.
As we requested, we have 3 items on the first page.
There's also two extra fields ``next`` and ``prev``,
which help us navigate to other pages.
Since we're on the first page, there is no previous page, which is why ``prev`` is empty.
If we wished to go to the next page, we'd make the same request with the new page number.

View File

@ -1,2 +1,61 @@
Permissions
===========
Sachet offers a selection of permissions that can be assigned to users,
which manage their access to certain endpoints.
Serialization
-------------
In Sachet's JSON API, permissions are serialized as an array of string codes.
These codes are documented in :ref:`permissions_table`.
For instance, here is an example output for ``GET /users/user``:
.. code-block:: json
{
"permissions": [
"CREATE",
"DELETE",
"LIST",
"READ"
],
"register_date": "2023-05-08T18:57:27.982479",
"username": "user"
}
.. _permissions_table:
Table of permissions
--------------------
The following is a table of permissions Sachet offers, and what they do:
.. list-table::
:widths: 25 25 50
:header-rows: 1
* - Permission
- Code
- Description
* - Create shares
- ``CREATE``
- Allows uploading files to Sachet.
* - Modify shares
- ``MODIFY``
- Allows users to modify their own shares' contents and metadata.
* - Delete shares
- ``DELETE``
- Allows users to delete any share.
* - Lock shares
- ``LOCK``
- Allows users to lock and unlock shares (see :ref:`files_lock_api`).
* - List shares
- ``LIST``
- Allows users to list all shares from all users.
* - Read shares
- ``READ``
- Allows users to read any share.
* - Administration
- ``ADMIN``
- Allows creating users and managing their permissions.

View File

@ -1,2 +1,141 @@
User API
========
.. _user_schema:
User Schema
-----------
In JSON, a User object has the following properties:
.. code-block:: json
{
"username": "<username>",
"password": "<password>",
"permissions": ["PERMISSION1", "PERMISSION2"],
"register_date": "2023-05-08T18:57:27.982479"
}
.. list-table::
:header-rows: 1
:widths: 25 25 25 50
* - Property
- Type
- Limits
- Description
* - ``username``
- String
-
- User's name. This also acts as an ID.
* - ``password``
- String
- Write-only
- Password in plain text.
* - ``permissions``
- List of String
-
- List of permissions (see :ref:`permissions_table`).
* - ``register_date``
- DateTime
- Read-only
- Time the user registered at.
.. _user_info_api:
User Info API
-------------
The User Info API allows managing users and their permissions.
Sachet implements the following endpoints for this API::
GET /users/<username>
PATCH /users/<username>
PUT /users/<username>
GET
^^^
Requesting ``GET /users/<username>`` returns a JSON object conforming to the :ref:`User schema<user_schema>`.
This contains the information about the specified username.
An example response:
.. code-block:: json
{
"permissions": [
"CREATE",
"DELETE",
"LIST",
"READ"
],
"register_date": "2023-05-08T18:57:27.982479",
"username": "user"
}
A user can only read information about themselves, unless they have the :ref:`administrator permission<permissions_table>`.
PATCH
^^^^^
Requesting ``PATCH /users/<username>`` allows modifying some or all fields of a user.
The request body is JSON conforming to the :ref:`User schema<user_schema>`.
Properties may be left out: they won't be modified.
For example, to modify a user's permissions:
.. code-block:: json
{
"permissions": [
"CREATE"
]
}
Only :ref:`administrators<permissions_table>` can request this method.
PUT
^^^
Requesting ``PUT /users/<username>`` completely replaces a user's information.
The request body is JSON conforming to the :ref:`User schema<user_schema>`.
No property may be left out.
For example:
.. code-block:: json
{
"permissions": [
"CREATE"
],
"password": "123",
"username": "user"
}
Only :ref:`administrators<permissions_table>` can request this method.
.. _user_list_api:
List API
--------
There is also a User List API::
GET /users
POST /users
This API is only accessible to administrators (see :ref:`permissions_table`).
GET
^^^
``GET /users`` is a :ref:`paginated endpoint<pagination>` that returns a list of users.
POST
^^^^
``POST /users`` creates a new user.
The request body must conform to the :ref:`User schema<user_schema>`.