refactor: rewrite entire codebase in axum instead of actix
Replaces actix with axum for web, allows us to use socket.io and gives us access to the tower ecosystem of middleware breaks compatibility with our current websocket implementation, needs to be reimplemented for socket.io
This commit is contained in:
parent
3647086adb
commit
324137ce8b
47 changed files with 1381 additions and 1129 deletions
|
@ -1,12 +1,24 @@
|
|||
use actix_web::{Scope, web};
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
Router,
|
||||
routing::{delete, get, patch},
|
||||
};
|
||||
//use socketioxide::SocketIo;
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
mod uuid;
|
||||
|
||||
pub fn web() -> Scope {
|
||||
web::scope("/channels")
|
||||
.service(uuid::get)
|
||||
.service(uuid::delete)
|
||||
.service(uuid::patch)
|
||||
.service(uuid::messages::get)
|
||||
.service(uuid::socket::ws)
|
||||
pub fn router() -> Router<Arc<AppState>> {
|
||||
//let (layer, io) = SocketIo::new_layer();
|
||||
|
||||
//io.ns("/{uuid}/socket", uuid::socket::ws);
|
||||
|
||||
Router::new()
|
||||
.route("/{uuid}", get(uuid::get))
|
||||
.route("/{uuid}", delete(uuid::delete))
|
||||
.route("/{uuid}", patch(uuid::patch))
|
||||
.route("/{uuid}/messages", get(uuid::messages::get))
|
||||
//.layer(layer)
|
||||
}
|
||||
|
|
|
@ -1,18 +1,29 @@
|
|||
//! `/api/v1/channels/{uuid}/messages` Endpoints related to channel messages
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
Data,
|
||||
AppState,
|
||||
api::v1::auth::check_access_token,
|
||||
error::Error,
|
||||
objects::{Channel, Member},
|
||||
utils::{get_auth_header, global_checks},
|
||||
utils::global_checks,
|
||||
};
|
||||
use ::uuid::Uuid;
|
||||
use actix_web::{HttpRequest, HttpResponse, get, web};
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Path, Query, State},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
};
|
||||
use axum_extra::{
|
||||
TypedHeader,
|
||||
headers::{Authorization, authorization::Bearer},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MessageRequest {
|
||||
pub struct MessageRequest {
|
||||
amount: i64,
|
||||
offset: i64,
|
||||
}
|
||||
|
@ -47,32 +58,25 @@ struct MessageRequest {
|
|||
/// });
|
||||
/// ```
|
||||
///
|
||||
#[get("/{uuid}/messages")]
|
||||
pub async fn get(
|
||||
req: HttpRequest,
|
||||
path: web::Path<(Uuid,)>,
|
||||
message_request: web::Query<MessageRequest>,
|
||||
data: web::Data<Data>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let headers = req.headers();
|
||||
State(app_state): State<Arc<AppState>>,
|
||||
Path(channel_uuid): Path<Uuid>,
|
||||
Query(message_request): Query<MessageRequest>,
|
||||
TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
|
||||
) -> Result<impl IntoResponse, Error> {
|
||||
let mut conn = app_state.pool.get().await?;
|
||||
|
||||
let auth_header = get_auth_header(headers)?;
|
||||
let uuid = check_access_token(auth.token(), &mut conn).await?;
|
||||
|
||||
let channel_uuid = path.into_inner().0;
|
||||
global_checks(&app_state, uuid).await?;
|
||||
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
||||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
let channel = Channel::fetch_one(&app_state, channel_uuid).await?;
|
||||
|
||||
Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
let messages = channel
|
||||
.fetch_messages(&data, message_request.amount, message_request.offset)
|
||||
.fetch_messages(&app_state, message_request.amount, message_request.offset)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(messages))
|
||||
Ok((StatusCode::OK, Json(messages)))
|
||||
}
|
||||
|
|
|
@ -1,77 +1,74 @@
|
|||
//! `/api/v1/channels/{uuid}` Channel specific endpoints
|
||||
|
||||
pub mod messages;
|
||||
pub mod socket;
|
||||
//pub mod socket;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
Data,
|
||||
AppState,
|
||||
api::v1::auth::check_access_token,
|
||||
error::Error,
|
||||
objects::{Channel, Member, Permissions},
|
||||
utils::{get_auth_header, global_checks},
|
||||
utils::global_checks,
|
||||
};
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Path, State},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
};
|
||||
use axum_extra::{
|
||||
TypedHeader,
|
||||
headers::{Authorization, authorization::Bearer},
|
||||
};
|
||||
use actix_web::{HttpRequest, HttpResponse, delete, get, patch, web};
|
||||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[get("/{uuid}")]
|
||||
pub async fn get(
|
||||
req: HttpRequest,
|
||||
path: web::Path<(Uuid,)>,
|
||||
data: web::Data<Data>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let headers = req.headers();
|
||||
State(app_state): State<Arc<AppState>>,
|
||||
Path(channel_uuid): Path<Uuid>,
|
||||
TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
|
||||
) -> Result<impl IntoResponse, Error> {
|
||||
let mut conn = app_state.pool.get().await?;
|
||||
|
||||
let auth_header = get_auth_header(headers)?;
|
||||
let uuid = check_access_token(auth.token(), &mut conn).await?;
|
||||
|
||||
let channel_uuid = path.into_inner().0;
|
||||
global_checks(&app_state, uuid).await?;
|
||||
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
||||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
let channel = Channel::fetch_one(&app_state, channel_uuid).await?;
|
||||
|
||||
Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(channel))
|
||||
Ok((StatusCode::OK, Json(channel)))
|
||||
}
|
||||
|
||||
#[delete("/{uuid}")]
|
||||
pub async fn delete(
|
||||
req: HttpRequest,
|
||||
path: web::Path<(Uuid,)>,
|
||||
data: web::Data<Data>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let headers = req.headers();
|
||||
State(app_state): State<Arc<AppState>>,
|
||||
Path(channel_uuid): Path<Uuid>,
|
||||
TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
|
||||
) -> Result<impl IntoResponse, Error> {
|
||||
let mut conn = app_state.pool.get().await?;
|
||||
|
||||
let auth_header = get_auth_header(headers)?;
|
||||
let uuid = check_access_token(auth.token(), &mut conn).await?;
|
||||
|
||||
let channel_uuid = path.into_inner().0;
|
||||
global_checks(&app_state, uuid).await?;
|
||||
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
||||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
let channel = Channel::fetch_one(&app_state, channel_uuid).await?;
|
||||
|
||||
let member = Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
member
|
||||
.check_permission(&data, Permissions::ManageChannel)
|
||||
.check_permission(&app_state, Permissions::ManageChannel)
|
||||
.await?;
|
||||
|
||||
channel.delete(&data).await?;
|
||||
channel.delete(&app_state).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().finish())
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct NewInfo {
|
||||
pub struct NewInfo {
|
||||
name: Option<String>,
|
||||
description: Option<String>,
|
||||
is_above: Option<String>,
|
||||
|
@ -108,48 +105,41 @@ struct NewInfo {
|
|||
/// });
|
||||
/// ```
|
||||
/// NOTE: UUIDs in this response are made using `uuidgen`, UUIDs made by the actual backend will be UUIDv7 and have extractable timestamps
|
||||
#[patch("/{uuid}")]
|
||||
pub async fn patch(
|
||||
req: HttpRequest,
|
||||
path: web::Path<(Uuid,)>,
|
||||
new_info: web::Json<NewInfo>,
|
||||
data: web::Data<Data>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let headers = req.headers();
|
||||
State(app_state): State<Arc<AppState>>,
|
||||
Path(channel_uuid): Path<Uuid>,
|
||||
TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
|
||||
Json(new_info): Json<NewInfo>,
|
||||
) -> Result<impl IntoResponse, Error> {
|
||||
let mut conn = app_state.pool.get().await?;
|
||||
|
||||
let auth_header = get_auth_header(headers)?;
|
||||
let uuid = check_access_token(auth.token(), &mut conn).await?;
|
||||
|
||||
let channel_uuid = path.into_inner().0;
|
||||
global_checks(&app_state, uuid).await?;
|
||||
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
||||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
let mut channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
let mut channel = Channel::fetch_one(&app_state, channel_uuid).await?;
|
||||
|
||||
let member = Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
member
|
||||
.check_permission(&data, Permissions::ManageChannel)
|
||||
.check_permission(&app_state, Permissions::ManageChannel)
|
||||
.await?;
|
||||
|
||||
if let Some(new_name) = &new_info.name {
|
||||
channel.set_name(&data, new_name.to_string()).await?;
|
||||
channel.set_name(&app_state, new_name.to_string()).await?;
|
||||
}
|
||||
|
||||
if let Some(new_description) = &new_info.description {
|
||||
channel
|
||||
.set_description(&data, new_description.to_string())
|
||||
.set_description(&app_state, new_description.to_string())
|
||||
.await?;
|
||||
}
|
||||
|
||||
if let Some(new_is_above) = &new_info.is_above {
|
||||
channel
|
||||
.set_description(&data, new_is_above.to_string())
|
||||
.set_description(&app_state, new_is_above.to_string())
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(HttpResponse::Ok().json(channel))
|
||||
Ok((StatusCode::OK, Json(channel)))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue