Compare commits
10 Commits
a8f22fb741
...
5fd8fada2c
Author | SHA1 | Date | |
---|---|---|---|
5fd8fada2c | |||
281ad30eec | |||
c0947ebbe2 | |||
089b14e6c9 | |||
4a80d4097e | |||
9bbd87ed36 | |||
1f7ade3c1f | |||
2914ff7856 | |||
4a55ad7ac0 | |||
a9b263f33c |
@ -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.
|
||||
|
293
docs/files.rst
293
docs/files.rst
@ -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`.
|
||||
|
@ -11,6 +11,7 @@ Welcome to Sachet's documentation!
|
||||
:caption: Contents:
|
||||
|
||||
authentication
|
||||
pagination
|
||||
permissions
|
||||
user
|
||||
admin
|
||||
|
54
docs/pagination.rst
Normal file
54
docs/pagination.rst
Normal 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.
|
@ -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.
|
||||
|
139
docs/user.rst
139
docs/user.rst
@ -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>`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user