diff --git a/.gitignore b/.gitignore index a683cefa..89183272 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ config.yaml */*_modules/ .coverage .cache +__pycache__ +.idea/ +*.iml +data/ \ No newline at end of file diff --git a/API.md b/API.md index 62e0eb22..ae2bb6b3 100644 --- a/API.md +++ b/API.md @@ -7,6 +7,7 @@ 1. [General rules](#general-rules) - [Authentication](#authentication) + - [User token authentication](#user-token-authentication) - [Basic requests](#basic-requests) - [File uploads](#file-uploads) - [Error handling](#error-handling) @@ -56,6 +57,11 @@ - [Updating user](#updating-user) - [Getting user](#getting-user) - [Deleting user](#deleting-user) + - User Tokens + - [Listing tokens](#listing-tokens) + - [Creating token](#creating-token) + - [Updating token](#updating-token) + - [Deleting token](#deleting-token) - Password reset - [Password reset - step 1: mail request](#password-reset---step-2-confirmation) - [Password reset - step 2: confirmation](#password-reset---step-2-confirmation) @@ -70,6 +76,7 @@ - [User](#user) - [Micro user](#micro-user) + - [User token](#user-token) - [Tag category](#tag-category) - [Tag](#tag) - [Micro tag](#micro-tag) @@ -91,16 +98,35 @@ ## Authentication Authentication is achieved by means of [basic HTTP -auth](https://en.wikipedia.org/wiki/Basic_access_authentication). For this -reason, it is recommended to connect through HTTPS. There are no sessions, so -every privileged request must be authenticated. Available privileges depend on -the user's rank. The way how rank translates to privileges is defined in the -server's configuration. +auth](https://en.wikipedia.org/wiki/Basic_access_authentication) or through the +use of [user token authentication](#user-token-authentication). For this reason, +it is recommended to connect through HTTPS. There are no sessions, so every +privileged request must be authenticated. Available privileges depend on the +user's rank. The way how rank translates to privileges is defined in the server's +configuration. It is recommended to add `?bump-login` GET parameter to the first request in a client "session" (where the definition of a session is up to the client), so that the user's last login time is kept up to date. +## User token authentication + +User token authentication works similarly to [basic HTTP +auth](https://en.wikipedia.org/wiki/Basic_access_authentication). Because it +operates similarly to ***basic HTTP auth*** it is still recommended to connect +through HTTPS. The authorization header uses the type of Token and the username +and token are encoded as Base64 and sent as the second parameter. + +Example header for user1:token-is-more-secure +``` +Authorization: Token dXNlcjE6dG9rZW4taXMtbW9yZS1zZWN1cmU= +``` + +The benefit of token authentication is that beyond the initial login to acquire +the first token, there is no need to transmit the user password in plaintext via +basic auth. Additionally tokens can be revoked at anytime allowing a cleaner +interface for isolating clients from user credentials. + ## Basic requests Every request must use `Content-Type: application/json` and `Accept: @@ -1469,6 +1495,104 @@ data. Deletes existing user. +## Listing tokens +- **Request** + + `GET /user-tokens/` + +- **Output** + + An [unpaged search result resource](#unpaged-search-result), for which + `` is a [user token resource](#user-token). + +- **Errors** + + - privileges are too low + +- **Description** + + Searches for users tokens for the currently logged in user. + +## Creating token +- **Request** + + `POST /user-token` + +- **Input** + + ```json5 + {} + ``` + +- **Output** + + A [user token resource](#user-token). + +- **Errors** + + - privileges are too low + +- **Description** + + Creates a new user token that can be used for authentication of api + endpoints instead of a password. + +## Updating user +- **Request** + + `PUT /user-token/` + +- **Input** + + ```json5 + { + "version": , + "enabled": , // optional + } + ``` + +- **Output** + + A [user token resource](#user-token). + +- **Errors** + + - the version is outdated + - the user token does not exist + - privileges are too low + +- **Description** + + Updates an existing user token using specified parameters. All fields + except the [`version`](#versioning) are optional - update concerns only + provided fields. + +## Deleting token +- **Request** + + `DELETE /user-token/` + +- **Input** + + ```json5 + {} + ``` + +- **Output** + + ```json5 + {} + ``` + +- **Errors** + + - the token does not exist + - privileges are too low + +- **Description** + + Deletes existing user token. + ## Password reset - step 1: mail request - **Request** @@ -1701,6 +1825,32 @@ A single user. A [user resource](#user) stripped down to `name` and `avatarUrl` fields. +## User token +**Description** + +A single user token. + +**Structure** + +```json5 +{ + "user": , + "token": , + "enabled": , + "version": , + "creationTime": , + "lastEditTime": , +} +``` + +**Field meaning** +- ``: micro user. See [micro user](#micro-user). +- ``: the token that can be used to authenticate the user. +- ``: whether the token is still valid for authentication. +- ``: resource version. See [versioning](#versioning). +- ``: time the user token was created , formatted as per RFC 3339. +- ``: time the user token was edited, formatted as per RFC 3339. + ## Tag category **Description** diff --git a/client/css/user-view.styl b/client/css/user-view.styl index 12cba75e..46f3044a 100644 --- a/client/css/user-view.styl +++ b/client/css/user-view.styl @@ -1,6 +1,6 @@ #user width: 100% - max-width: 35em + max-width: 45em nav.text-nav margin-bottom: 1.5em @@ -37,6 +37,24 @@ height: 1px clear: both + #user-tokens + .token-flex-container + width: 100% + display: flex; + flex-direction column; + padding-bottom: 0.5em; + + .token-flex-row + display: flex; + flex-direction: row; + justify-content: space-between; + padding-top: 0.25em; + padding-bottom: 0.25em; + border-bottom: black solid 1px; + + form + width: auto; + #user-delete form width: 100% diff --git a/client/html/user.tpl b/client/html/user.tpl index 28e34e67..cbf4f18f 100644 --- a/client/html/user.tpl +++ b/client/html/user.tpl @@ -6,6 +6,9 @@ --><% if (ctx.canEditAnything) { %>
  • '>Account settings
  • <% } %><% if (ctx.canListTokens) { %>
  • '>Manage tokens
  • <% } %><% if (ctx.canDelete) { %>
  • '>Account deletion
  • <% } %>