mirror of
https://github.com/Steffo99/distributed-arcade.git
synced 2024-11-24 17:14:25 +00:00
Gate POST /board/
with the envvar CREATE_TOKEN
This commit is contained in:
parent
610ba76cc4
commit
8c9996e83a
5 changed files with 42 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/target
|
/target
|
||||||
/data
|
/data
|
||||||
|
/secrets
|
||||||
|
|
|
@ -17,5 +17,6 @@ services:
|
||||||
environment:
|
environment:
|
||||||
REDIS_CONN_STRING: "redis://redis:6379/"
|
REDIS_CONN_STRING: "redis://redis:6379/"
|
||||||
AXUM_HOST_STRING: "0.0.0.0:80"
|
AXUM_HOST_STRING: "0.0.0.0:80"
|
||||||
|
env_file: "./secrets/distributedarcade.env"
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:30038:80" # Reverse proxy this!
|
- "127.0.0.1:30038:80" # Reverse proxy this!
|
||||||
|
|
|
@ -7,6 +7,7 @@ POST http://localhost:30000/
|
||||||
### Create a board
|
### Create a board
|
||||||
POST http://localhost:30000/board/
|
POST http://localhost:30000/board/
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer qwertyxyzzy
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "example",
|
"name": "example",
|
||||||
|
|
|
@ -116,6 +116,8 @@ paths:
|
||||||
- using the `Descending` order, higher scores are better ranked than lower scores, like in arcade games or athletics.
|
- using the `Descending` order, higher scores are better ranked than lower scores, like in arcade games or athletics.
|
||||||
|
|
||||||
**WARNING: Once created, a board cannot be edited or deleted, and its token will not be accessible any longer!**
|
**WARNING: Once created, a board cannot be edited or deleted, and its token will not be accessible any longer!**
|
||||||
|
|
||||||
|
Requires an authorization key, set as the `CREATE_TOKEN` environment variable of the server.
|
||||||
tags: ["Board"]
|
tags: ["Board"]
|
||||||
requestBody:
|
requestBody:
|
||||||
required: true
|
required: true
|
||||||
|
@ -135,6 +137,8 @@ paths:
|
||||||
enum:
|
enum:
|
||||||
- "Ascending"
|
- "Ascending"
|
||||||
- "Descending"
|
- "Descending"
|
||||||
|
security:
|
||||||
|
- XCreateToken: []
|
||||||
responses:
|
responses:
|
||||||
201:
|
201:
|
||||||
description: "Board created successfully"
|
description: "Board created successfully"
|
||||||
|
@ -152,6 +156,20 @@ paths:
|
||||||
operationId: "putScore"
|
operationId: "putScore"
|
||||||
parameters:
|
parameters:
|
||||||
board: "$response.body/name"
|
board: "$response.body/name"
|
||||||
|
401:
|
||||||
|
description: "Missing, invalid or malformed Authorization header"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: "Missing Authorization header"
|
||||||
|
403:
|
||||||
|
description: "Invalid create token"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: "Invalid create token"
|
||||||
409:
|
409:
|
||||||
description: "Board already exists"
|
description: "Board already exists"
|
||||||
content:
|
content:
|
||||||
|
@ -257,6 +275,13 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
example: "Missing Authorization header"
|
example: "Missing Authorization header"
|
||||||
|
403:
|
||||||
|
description: "Invalid board token"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: "Invalid board token"
|
||||||
502:
|
502:
|
||||||
$ref: "#/components/responses/RedisCmdFailed"
|
$ref: "#/components/responses/RedisCmdFailed"
|
||||||
504:
|
504:
|
||||||
|
@ -265,6 +290,10 @@ paths:
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
|
XCreateToken:
|
||||||
|
type: http
|
||||||
|
scheme: "Bearer"
|
||||||
|
bearerFormat: "setInEnvVars"
|
||||||
XBoardToken:
|
XBoardToken:
|
||||||
type: http
|
type: http
|
||||||
scheme: "Bearer"
|
scheme: "Bearer"
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
//! Module defining routes for `/board/`.
|
//! Module defining routes for `/board/`.
|
||||||
|
|
||||||
use axum::http::StatusCode;
|
use axum::http::{HeaderMap, StatusCode};
|
||||||
use axum::extract::{Extension, Json, Query};
|
use axum::extract::{Extension, Json, Query};
|
||||||
use redis::AsyncCommands;
|
use redis::AsyncCommands;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use crate::outcome;
|
use crate::outcome;
|
||||||
use crate::shortcuts::redis::RedisConnectOr504;
|
use crate::shortcuts::redis::RedisConnectOr504;
|
||||||
use crate::shortcuts::token::Generate;
|
use crate::shortcuts::token::{Authorize, Generate};
|
||||||
use crate::utils::sorting::SortingOrder;
|
use crate::utils::sorting::SortingOrder;
|
||||||
use crate::utils::kebab::Skewer;
|
use crate::utils::kebab::Skewer;
|
||||||
use crate::utils::token::SecureToken;
|
use crate::utils::token::SecureToken;
|
||||||
|
use crate::config;
|
||||||
|
|
||||||
|
|
||||||
/// Expected body for [`POST /board/`](route_board_post).
|
/// Expected body for [`POST /board/`](route_board_post).
|
||||||
|
@ -118,19 +119,18 @@ pub(crate) async fn route_board_get(
|
||||||
|
|
||||||
|
|
||||||
/// Handler for `POST /board/`.
|
/// Handler for `POST /board/`.
|
||||||
///
|
|
||||||
/// Creates a new board, storing the details on [Redis].
|
|
||||||
///
|
|
||||||
/// Will refuse to overwrite an already existing board.
|
|
||||||
///
|
|
||||||
/// Be aware that once created, boards cannot be deleted, if not manually via `redis-cli`.
|
|
||||||
///
|
|
||||||
/// If successful, returns [`StatusCode::CREATED`].
|
|
||||||
pub(crate) async fn route_board_post(
|
pub(crate) async fn route_board_post(
|
||||||
|
headers: HeaderMap,
|
||||||
Extension(rclient): Extension<redis::Client>,
|
Extension(rclient): Extension<redis::Client>,
|
||||||
Json(RouteBoardBody {name, order}): Json<RouteBoardBody>,
|
Json(RouteBoardBody {name, order}): Json<RouteBoardBody>,
|
||||||
) -> outcome::RequestResult {
|
) -> outcome::RequestResult {
|
||||||
|
|
||||||
|
let token = headers.get_authorization_or_401("Bearer")?;
|
||||||
|
if token != config::CREATE_TOKEN.as_str() {
|
||||||
|
log::trace!("Token does not match, forbidding...");
|
||||||
|
return Err((StatusCode::FORBIDDEN, outcome::req_error!("Invalid create token")))
|
||||||
|
}
|
||||||
|
|
||||||
let name = name.to_kebab_lowercase();
|
let name = name.to_kebab_lowercase();
|
||||||
|
|
||||||
log::trace!("Determining the Redis key names...");
|
log::trace!("Determining the Redis key names...");
|
||||||
|
|
Loading…
Reference in a new issue