Skip to content

Commit

Permalink
Merge pull request #1 from vswarte/feat/ban-api
Browse files Browse the repository at this point in the history
Ban API
  • Loading branch information
vswarte authored Aug 22, 2024
2 parents 93e80da + 60595f9 commit 41f9d70
Show file tree
Hide file tree
Showing 28 changed files with 332 additions and 195 deletions.
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"crates/config",
"crates/connection",
"crates/rpc",
"crates/session",
]

[profile.release]
Expand Down Expand Up @@ -105,3 +106,6 @@ path = "crates/connection"

[workspace.dependencies.waygate-rpc]
path = "crates/rpc"

[workspace.dependencies.waygate-session]
path = "crates/session"
12 changes: 12 additions & 0 deletions crates/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ edition = "2021"
[dependencies]
actix-web = "4"

[dependencies.sqlx]
workspace = true

[dependencies.thiserror]
workspace = true

Expand All @@ -15,6 +18,9 @@ workspace = true
[dependencies.rand]
workspace = true

[dependencies.tracing]
workspace = true

[dependencies.waygate-config]
workspace = true

Expand All @@ -23,3 +29,9 @@ workspace = true

[dependencies.waygate-connection]
workspace = true

[dependencies.waygate-database]
workspace = true

[dependencies.waygate-session]
workspace = true
59 changes: 59 additions & 0 deletions crates/api/src/ban.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::error::Error;

use actix_web::web::{Json, Path, Query};
use actix_web::{delete, get, post, Responder};
use serde::{Deserialize, Serialize};
use sqlx::{query, query_as, Row};
use waygate_database::database_connection;
use waygate_session::{clear_bans, create_ban};

use crate::pagination::{PaginatedResponse, PaginationParameters};

const DEFAULT_INDEX_LIMIT: i32 = 100;

#[get("/ban")]
async fn get_ban(
Query(pagination): Query<PaginationParameters>,
) -> Result<impl Responder, Box<dyn Error>> {
let mut connection = database_connection().await?;

// TODO: make a single query
let total: i64 = query("SELECT COUNT(ban_id) as total FROM bans")
.fetch_one(&mut *connection)
.await?
.get("total");

let entries = query_as::<_, Ban>("SELECT * FROM bans ORDER BY ban_id LIMIT $1 OFFSET $2")
.bind(pagination.limit.as_ref().unwrap_or(&DEFAULT_INDEX_LIMIT))
.bind(pagination.offset.as_ref().unwrap_or(&0))
.fetch_all(&mut *connection)
.await?
.into_iter()
.collect::<Vec<_>>();

Ok(Json(PaginatedResponse::new(total, entries)))
}

#[post("/ban")]
async fn post_ban(request: Json<NewBan>) -> Result<impl Responder, Box<dyn Error>> {
let ban_id = create_ban(&request.external_id).await?;
Ok(Json(ban_id))
}

#[delete("/ban/{external_id}")]
async fn delete_ban(external_id: Path<(String,)>) -> Result<impl Responder, Box<dyn Error>> {
let external_id = &external_id.into_inner().0;
clear_bans(external_id).await?;
Ok(Json(true))
}

#[derive(Debug, Serialize, sqlx::FromRow)]
struct Ban {
ban_id: i32,
external_id: String,
}

#[derive(Debug, Deserialize)]
struct NewBan {
external_id: String,
}
5 changes: 5 additions & 0 deletions crates/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use actix_web::{get, http::header::ContentType, App, HttpResponse, HttpServer, R
use thiserror::Error;

mod auth;
mod ban;
mod notify;
mod pagination;

use auth::CheckKey;

Expand All @@ -20,6 +22,9 @@ pub async fn serve_api(bind: &str, api_key: &str) -> Result<(), ApiError> {
.wrap(CheckKey::new(&api_key))
.service(health)
.service(notify::notify_message)
.service(ban::get_ban)
.service(ban::post_ban)
.service(ban::delete_ban)
})
.bind(bind)?
.run()
Expand Down
35 changes: 35 additions & 0 deletions crates/api/src/pagination.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use serde::{Deserialize, Serialize};


#[derive(Deserialize)]
pub struct PaginationParameters {
pub limit: Option<i32>,
pub offset: Option<i32>,
}

#[derive(Serialize)]
pub struct PaginatedResponse<T> {
pagination: PaginatedResponseMeta,
data: Vec<T>,
}

#[derive(Serialize)]
struct PaginatedResponseMeta {
total: i64,
count: usize,
}

impl<T> PaginatedResponse<T> {
pub fn new(total: i64, data: Vec<T>) -> Self {
let count = data.len();
let pagination = PaginatedResponseMeta {
total,
count,
};

Self {
pagination,
data
}
}
}
10 changes: 7 additions & 3 deletions crates/connection/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::future::Future;
use std::io::{self, Read, Write};
use std::net::SocketAddr;
use std::sync::Arc;
use base64::DecodeError;
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
use thiserror::Error;
Expand All @@ -10,7 +11,7 @@ use futures_util::SinkExt;
use waygate_message::{PayloadType, RequestParams, ResponseParams};
use waygate_wire::{deserialize, serialize, FNWireError};

use crate::{add_client_channel, handle_create_session, handle_restore_session, new_client_crypto, ClientPushChannelRX, ClientSession, ClientSessionContainer, CryptoError};
use crate::{add_client_channel, handle_create_session, handle_restore_session, new_client_crypto, ClientPushChannelRX, ClientSession, CryptoError};
use crate::ClientCrypto;
use crate::ClientCryptoStateActiveSession;
use crate::ClientCryptoStateParametersGenerated;
Expand Down Expand Up @@ -50,6 +51,9 @@ pub enum ClientError {

#[error("Bootstrap keys decode failed. {0}")]
Decode(#[from] DecodeError),

#[error("Player has been banned.")]
Banned,
}

#[derive(Debug, Error)]
Expand Down Expand Up @@ -324,7 +328,7 @@ impl Client<ClientStateReceivedSessionDetails> {
.await.map_err(|e| ClientError::Transport(TransportError::WriteFailed(e)))?;

let (push_tx, push_rx) = channel(25);
let player_id = session.lock_read().player_id;
let player_id = session.player_id;
add_client_channel(player_id, push_tx).await;

Ok(Client {
Expand All @@ -333,7 +337,7 @@ impl Client<ClientStateReceivedSessionDetails> {
state: ClientStateAuthenticated {
transport: self.state.transport,
crypto: self.state.crypto,
session,
session: Arc::new(session),
push_rx,
dispatch,
}
Expand Down
1 change: 0 additions & 1 deletion crates/connection/src/crypto.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::ffi::c_void;
use std::io::{self, Read};
use std::sync::OnceLock;
use libsodium_sys::{
crypto_kx_PUBLICKEYBYTES,
crypto_kx_SECRETKEYBYTES,
Expand Down
Loading

0 comments on commit 41f9d70

Please sign in to comment.