diff --git a/docs/source/overview/server.md b/docs/source/overview/server.md index 0d27a89b43279fbbc46b42740a38c678f3747c7d..8c7277b9e4de6add1a938872e9e085b1ef5c2944 100644 --- a/docs/source/overview/server.md +++ b/docs/source/overview/server.md @@ -37,7 +37,7 @@ When the server receives an API call it will first check that the call is author The authorization is done using JSON Web Tokens (JWT) by comparing the contents of them with what is expected. Whenever a client logs into an account or joins a competition, it is given a JWT generated by the server, and the client will need to use this token in every subsequent request sent to the server in order to authenticate itself. -The needed authorization is specified by the `@protect_route()` decorator. +The needed authorization is specified by the `ExtendedBlueprint.authorization()` decorator. This decorator specifies who is allowed to access this route, which can either be users with specific roles, or people that have joined competitions with specific views. If the route is not decorated everyone is allowed to access it, and the only routes currently like that is, by necessity, logging in as a user and joining a competition. @@ -53,9 +53,9 @@ This is why the server can simply read the contents of the JWT to be sure that t ### Parsing request -After the request is authorized the server will need to parse the contents of the request. -The parsing is done with [reqparse](https://flask-restx.readthedocs.io/en/latest/parsing.html) from RestX (this module is deprecated and should be replaced). -Each API call expects different parameters in different places and this is specified in each of the files in `app/apis/` folder, together with the route. +The server receives data in three ways: In the query string, body and header. +The data in the body and header is sent in JSON format and needs to be converted into Python dictionaries. +What data a route needs is specified by a marshmallow schema and blueprint from flask-smorest. ### Handling request @@ -67,7 +67,7 @@ Everything related to the database is located in the `app/database/` folder. ### Responding When the server har processed the request it usually responds with an item from the database. -Converting a database object to json is done with [Marsmallow](https://marshmallow.readthedocs.io/en/stable/). +Converting a database object to json is done with marshmallow. This conversion is specified in two files in the folder `app/core/`. The file `schemas.py` converts a record in the database field by field. The file `rich_schemas.py` on the other hand converts an `id` in one table to an entire object in the another table, thus the name rich. @@ -76,18 +76,18 @@ In this way, for example, an entire competition with its teams, codes, slides an ## Active competitions Slides, timers, and answers needs to be synced during an active presentation. -This is done using SocketIO together with flask*socketio. +This is done using SocketIO together with flask-socketio. Sent events are also authorized via JWT, basically the same way as the for the API calls. -But for socket events, the decorator that is used to authenticate them is `@authorize_user()`. +But for socket events, the decorator that is used to authenticate them is `sockets.authorization()`. Whenever a client joins a competition they will connect via sockets. A single competition cannot be active more than once at the same time. This means that you will need to make a copy of a competition if you want to run the same competition at several locations at the same time. All of the functionality related to an active competition and sockets can be found in the file `app/core/sockets.py`. -The terms \_active competition* and _presentation_ are equivalent. +The terms _active competition_ and _presentation_ are equivalent. ### Starting and joing presentations -Whenever a code is typed in to the client it will be checked via the `api/auth/login/code` API call. +Whenever a code is typed in to the client it will be checked via the `api/auth/code` API call. If there is such a code and it was an operator code, the client will receive the JWT it will need to use to authenticate itself. If there is such a code and the associated competition is active, the client will also receive a JWT for its corresponding role. Both of these cases will be handled by the default `connect` event, using the JWT received from the API call. @@ -97,8 +97,9 @@ The server can see what is stored in the JWT and do different things depending o [comment]: # "What does `sync` mean? It isn't explained" -The operator will emit the `sync` event and provide either a slide or a timer to update it on the server. -The server will then send `sync` to all connected clients with the updated values, regardless of what was actually updated. -The server will also store the timer and active slide in order to `sync` clients when they join. -The operator can also emit `end_presentation` to disconnect all clients from its competitions. +There are two other events that is used. +The operator will emit the `sync` event to sync some values to all other clients connected to the same competition. +The server will then send `sync` to all connected clients with the values that was updated. +The server will also store these values and will sync these when a client joins a competition. +The operator can also emit `end_presentation` to disconnect all clients from its competition. This will also end the presentation.