Merge pull request 'Path style changes' (#19) from wip/style-changes into main
Reviewed-on: #19 # BREAKING CHANGES Allows removal or changing of the /api prefix Moves /servers to /guilds Moves /guilds/{uuid}/channels/{uuid} to /channels/{uuid} (to get channels or create one you still call the old endpoint)
This commit is contained in:
commit
aa37571b3b
24 changed files with 148 additions and 150 deletions
|
@ -18,7 +18,8 @@ RUN useradd --create-home --home-dir /gorb gorb
|
||||||
|
|
||||||
USER gorb
|
USER gorb
|
||||||
|
|
||||||
ENV WEB_URL=https://gorb.app/web/ \
|
ENV WEB_FRONTEND_URL=https://gorb.app/web/ \
|
||||||
|
WEB_BASE_PATH=/api \
|
||||||
DATABASE_USERNAME=gorb \
|
DATABASE_USERNAME=gorb \
|
||||||
DATABASE_PASSWORD=gorb \
|
DATABASE_PASSWORD=gorb \
|
||||||
DATABASE=gorb \
|
DATABASE=gorb \
|
||||||
|
|
|
@ -18,7 +18,7 @@ services:
|
||||||
- gorb-backend:/gorb
|
- gorb-backend:/gorb
|
||||||
environment:
|
environment:
|
||||||
#- RUST_LOG=debug
|
#- RUST_LOG=debug
|
||||||
- WEB_URL=https://gorb.app/web/
|
- WEB_FRONTEND_URL=https://gorb.app/web/
|
||||||
- DATABASE_USERNAME=gorb
|
- DATABASE_USERNAME=gorb
|
||||||
- DATABASE_PASSWORD=gorb
|
- DATABASE_PASSWORD=gorb
|
||||||
- DATABASE=gorb
|
- DATABASE=gorb
|
||||||
|
|
|
@ -16,7 +16,7 @@ services:
|
||||||
- gorb-backend:/gorb
|
- gorb-backend:/gorb
|
||||||
environment:
|
environment:
|
||||||
#- RUST_LOG=debug
|
#- RUST_LOG=debug
|
||||||
- WEB_URL=https://gorb.app/web/
|
- WEB_FRONTEND_URL=https://gorb.app/web/
|
||||||
- DATABASE_USERNAME=gorb
|
- DATABASE_USERNAME=gorb
|
||||||
- DATABASE_PASSWORD=gorb
|
- DATABASE_PASSWORD=gorb
|
||||||
- DATABASE=gorb
|
- DATABASE=gorb
|
||||||
|
|
|
@ -11,7 +11,8 @@ fi
|
||||||
if [ ! -f "/gorb/config/config.toml" ]; then
|
if [ ! -f "/gorb/config/config.toml" ]; then
|
||||||
cat > /gorb/config/config.toml <<EOF
|
cat > /gorb/config/config.toml <<EOF
|
||||||
[web]
|
[web]
|
||||||
url = "${WEB_URL}"
|
frontend_url = "${WEB_FRONTEND_URL}"
|
||||||
|
base_path = "${WEB_BASE_PATH}"
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
username = "${DATABASE_USERNAME}"
|
username = "${DATABASE_USERNAME}"
|
||||||
|
|
|
@ -6,6 +6,6 @@ use actix_web::web;
|
||||||
mod v1;
|
mod v1;
|
||||||
mod versions;
|
mod versions;
|
||||||
|
|
||||||
pub fn web() -> Scope {
|
pub fn web(path: &str) -> Scope {
|
||||||
web::scope("/api").service(v1::web()).service(versions::get)
|
web::scope(path.trim_end_matches('/')).service(v1::web()).service(versions::get)
|
||||||
}
|
}
|
||||||
|
|
11
src/api/v1/channels/mod.rs
Normal file
11
src/api/v1/channels/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
use actix_web::{web, Scope};
|
||||||
|
|
||||||
|
mod uuid;
|
||||||
|
|
||||||
|
pub fn web() -> Scope {
|
||||||
|
web::scope("/channels")
|
||||||
|
.service(uuid::get)
|
||||||
|
.service(uuid::delete)
|
||||||
|
.service(uuid::messages::get)
|
||||||
|
.service(uuid::socket::ws)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
//! `/api/v1/servers/{uuid}/channels/{uuid}/messages` Endpoints related to channel messages
|
//! `/api/v1/channels/{uuid}/messages` Endpoints related to channel messages
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::v1::auth::check_access_token, error::Error, structs::{Channel, Member}, utils::{get_auth_header, global_checks}, Data
|
api::v1::auth::check_access_token, error::Error, structs::{Channel, Member}, utils::{get_auth_header, global_checks}, Data
|
||||||
|
@ -13,7 +13,7 @@ struct MessageRequest {
|
||||||
offset: i64,
|
offset: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `GET /api/v1/servers/{uuid}/channels/{uuid}/messages` Returns user with the given UUID
|
/// `GET /api/v1/channels/{uuid}/messages` Returns user with the given UUID
|
||||||
///
|
///
|
||||||
/// requires auth: yes
|
/// requires auth: yes
|
||||||
///
|
///
|
||||||
|
@ -43,10 +43,10 @@ struct MessageRequest {
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[get("{uuid}/channels/{channel_uuid}/messages")]
|
#[get("/{uuid}/messages")]
|
||||||
pub async fn get(
|
pub async fn get(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
path: web::Path<(Uuid, Uuid)>,
|
path: web::Path<(Uuid,)>,
|
||||||
message_request: web::Query<MessageRequest>,
|
message_request: web::Query<MessageRequest>,
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
|
@ -54,7 +54,7 @@ pub async fn get(
|
||||||
|
|
||||||
let auth_header = get_auth_header(headers)?;
|
let auth_header = get_auth_header(headers)?;
|
||||||
|
|
||||||
let (guild_uuid, channel_uuid) = path.into_inner();
|
let channel_uuid = path.into_inner().0;
|
||||||
|
|
||||||
let mut conn = data.pool.get().await?;
|
let mut conn = data.pool.get().await?;
|
||||||
|
|
||||||
|
@ -62,18 +62,9 @@ pub async fn get(
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
global_checks(&data, uuid).await?;
|
||||||
|
|
||||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||||
|
|
||||||
let channel: Channel;
|
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||||
|
|
||||||
if let Ok(cache_hit) = data.get_cache_key(format!("{}", channel_uuid)).await {
|
|
||||||
channel = serde_json::from_str(&cache_hit)?
|
|
||||||
} else {
|
|
||||||
channel = Channel::fetch_one(&mut conn, channel_uuid).await?;
|
|
||||||
|
|
||||||
data.set_cache_key(format!("{}", channel_uuid), channel.clone(), 60)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let messages = channel
|
let messages = channel
|
||||||
.fetch_messages(&data, message_request.amount, message_request.offset)
|
.fetch_messages(&data, message_request.amount, message_request.offset)
|
60
src/api/v1/channels/uuid/mod.rs
Normal file
60
src/api/v1/channels/uuid/mod.rs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
pub mod messages;
|
||||||
|
pub mod socket;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
api::v1::auth::check_access_token, error::Error, structs::{Channel, Member}, utils::{get_auth_header, global_checks}, Data
|
||||||
|
};
|
||||||
|
use actix_web::{HttpRequest, HttpResponse, delete, get, web};
|
||||||
|
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();
|
||||||
|
|
||||||
|
let auth_header = get_auth_header(headers)?;
|
||||||
|
|
||||||
|
let channel_uuid = path.into_inner().0;
|
||||||
|
|
||||||
|
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?;
|
||||||
|
|
||||||
|
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::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();
|
||||||
|
|
||||||
|
let auth_header = get_auth_header(headers)?;
|
||||||
|
|
||||||
|
let channel_uuid = path.into_inner().0;
|
||||||
|
|
||||||
|
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?;
|
||||||
|
|
||||||
|
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||||
|
|
||||||
|
channel.delete(&data).await?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().finish())
|
||||||
|
}
|
|
@ -11,10 +11,10 @@ use crate::{
|
||||||
api::v1::auth::check_access_token, structs::{Channel, Member}, utils::{get_ws_protocol_header, global_checks}, Data
|
api::v1::auth::check_access_token, structs::{Channel, Member}, utils::{get_ws_protocol_header, global_checks}, Data
|
||||||
};
|
};
|
||||||
|
|
||||||
#[get("{uuid}/channels/{channel_uuid}/socket")]
|
#[get("/{uuid}/socket")]
|
||||||
pub async fn ws(
|
pub async fn ws(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
path: web::Path<(Uuid, Uuid)>,
|
path: web::Path<(Uuid,)>,
|
||||||
stream: web::Payload,
|
stream: web::Payload,
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
|
@ -24,8 +24,8 @@ pub async fn ws(
|
||||||
// Retrieve auth header
|
// Retrieve auth header
|
||||||
let auth_header = get_ws_protocol_header(headers)?;
|
let auth_header = get_ws_protocol_header(headers)?;
|
||||||
|
|
||||||
// Get uuids from path
|
// Get uuid from path
|
||||||
let (guild_uuid, channel_uuid) = path.into_inner();
|
let channel_uuid = path.into_inner().0;
|
||||||
|
|
||||||
let mut conn = data.pool.get().await.map_err(crate::error::Error::from)?;
|
let mut conn = data.pool.get().await.map_err(crate::error::Error::from)?;
|
||||||
|
|
||||||
|
@ -34,20 +34,10 @@ pub async fn ws(
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
global_checks(&data, uuid).await?;
|
||||||
|
|
||||||
|
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||||
|
|
||||||
// Get server member from psql
|
// Get server member from psql
|
||||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||||
|
|
||||||
let channel: Channel;
|
|
||||||
|
|
||||||
// Return channel cache or result from psql as `channel` variable
|
|
||||||
if let Ok(cache_hit) = data.get_cache_key(format!("{}", channel_uuid)).await {
|
|
||||||
channel = serde_json::from_str(&cache_hit)?
|
|
||||||
} else {
|
|
||||||
channel = Channel::fetch_one(&mut conn, channel_uuid).await?;
|
|
||||||
|
|
||||||
data.set_cache_key(format!("{}", channel_uuid), channel.clone(), 60)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (mut res, mut session_1, stream) = actix_ws::handle(&req, stream)?;
|
let (mut res, mut session_1, stream) = actix_ws::handle(&req, stream)?;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! `/api/v1/servers` Guild related endpoints
|
//! `/api/v1/guilds` Guild related endpoints
|
||||||
|
|
||||||
use actix_web::{HttpRequest, HttpResponse, Scope, get, post, web};
|
use actix_web::{HttpRequest, HttpResponse, Scope, get, post, web};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -15,13 +15,13 @@ struct GuildInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn web() -> Scope {
|
pub fn web() -> Scope {
|
||||||
web::scope("/servers")
|
web::scope("/guilds")
|
||||||
.service(post)
|
.service(post)
|
||||||
.service(get)
|
.service(get)
|
||||||
.service(uuid::web())
|
.service(uuid::web())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `POST /api/v1/servers` Creates a new guild
|
/// `POST /api/v1/guilds` Creates a new guild
|
||||||
///
|
///
|
||||||
/// requires auth: yes
|
/// requires auth: yes
|
||||||
///
|
///
|
|
@ -5,8 +5,6 @@ use ::uuid::Uuid;
|
||||||
use actix_web::{HttpRequest, HttpResponse, get, post, web};
|
use actix_web::{HttpRequest, HttpResponse, get, post, web};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
pub mod uuid;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct ChannelInfo {
|
struct ChannelInfo {
|
||||||
name: String,
|
name: String,
|
|
@ -1,4 +1,4 @@
|
||||||
//! `/api/v1/servers/{uuid}/icon` icon related endpoints, will probably be replaced by a multipart post to above endpoint
|
//! `/api/v1/guilds/{uuid}/icon` icon related endpoints, will probably be replaced by a multipart post to above endpoint
|
||||||
|
|
||||||
use actix_web::{HttpRequest, HttpResponse, put, web};
|
use actix_web::{HttpRequest, HttpResponse, put, web};
|
||||||
use futures_util::StreamExt as _;
|
use futures_util::StreamExt as _;
|
||||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
api::v1::auth::check_access_token, error::Error, structs::{Guild, Member}, utils::{get_auth_header, global_checks}, Data
|
api::v1::auth::check_access_token, error::Error, structs::{Guild, Member}, utils::{get_auth_header, global_checks}, Data
|
||||||
};
|
};
|
||||||
|
|
||||||
/// `PUT /api/v1/servers/{uuid}/icon` Icon upload
|
/// `PUT /api/v1/guilds/{uuid}/icon` Icon upload
|
||||||
///
|
///
|
||||||
/// requires auth: no
|
/// requires auth: no
|
||||||
///
|
///
|
|
@ -1,4 +1,4 @@
|
||||||
//! `/api/v1/servers/{uuid}` Specific server endpoints
|
//! `/api/v1/guilds/{uuid}` Specific server endpoints
|
||||||
|
|
||||||
use actix_web::{HttpRequest, HttpResponse, Scope, get, web};
|
use actix_web::{HttpRequest, HttpResponse, Scope, get, web};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -19,10 +19,6 @@ pub fn web() -> Scope {
|
||||||
// Channels
|
// Channels
|
||||||
.service(channels::get)
|
.service(channels::get)
|
||||||
.service(channels::create)
|
.service(channels::create)
|
||||||
.service(channels::uuid::get)
|
|
||||||
.service(channels::uuid::delete)
|
|
||||||
.service(channels::uuid::messages::get)
|
|
||||||
.service(channels::uuid::socket::ws)
|
|
||||||
// Roles
|
// Roles
|
||||||
.service(roles::get)
|
.service(roles::get)
|
||||||
.service(roles::create)
|
.service(roles::create)
|
||||||
|
@ -34,7 +30,7 @@ pub fn web() -> Scope {
|
||||||
.service(icon::upload)
|
.service(icon::upload)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `GET /api/v1/servers/{uuid}` DESCRIPTION
|
/// `GET /api/v1/guilds/{uuid}` DESCRIPTION
|
||||||
///
|
///
|
||||||
/// requires auth: yes
|
/// requires auth: yes
|
||||||
///
|
///
|
|
@ -1,11 +1,11 @@
|
||||||
//! `/api/v1/me/servers` Contains endpoint related to guild memberships
|
//! `/api/v1/me/guilds` Contains endpoint related to guild memberships
|
||||||
|
|
||||||
use actix_web::{get, web, HttpRequest, HttpResponse};
|
use actix_web::{get, web, HttpRequest, HttpResponse};
|
||||||
|
|
||||||
use crate::{api::v1::auth::check_access_token, error::Error, structs::Me, utils::{get_auth_header, global_checks}, Data};
|
use crate::{api::v1::auth::check_access_token, error::Error, structs::Me, utils::{get_auth_header, global_checks}, Data};
|
||||||
|
|
||||||
|
|
||||||
/// `GET /api/v1/me/servers` Returns all guild memberships in a list
|
/// `GET /api/v1/me/guilds` Returns all guild memberships in a list
|
||||||
///
|
///
|
||||||
/// requires auth: yes
|
/// requires auth: yes
|
||||||
///
|
///
|
||||||
|
@ -27,7 +27,7 @@ use crate::{api::v1::auth::check_access_token, error::Error, structs::Me, utils:
|
||||||
/// ]);
|
/// ]);
|
||||||
/// ```
|
/// ```
|
||||||
/// NOTE: UUIDs in this response are made using `uuidgen`, UUIDs made by the actual backend will be UUIDv7 and have extractable timestamps
|
/// NOTE: UUIDs in this response are made using `uuidgen`, UUIDs made by the actual backend will be UUIDv7 and have extractable timestamps
|
||||||
#[get("/servers")]
|
#[get("/guilds")]
|
||||||
pub async fn get(req: HttpRequest, data: web::Data<Data>) -> Result<HttpResponse, Error> {
|
pub async fn get(req: HttpRequest, data: web::Data<Data>) -> Result<HttpResponse, Error> {
|
||||||
let headers = req.headers();
|
let headers = req.headers();
|
||||||
|
|
|
@ -6,10 +6,13 @@ use crate::{
|
||||||
api::v1::auth::check_access_token, error::Error, structs::Me, utils::{get_auth_header, global_checks}, Data
|
api::v1::auth::check_access_token, error::Error, structs::Me, utils::{get_auth_header, global_checks}, Data
|
||||||
};
|
};
|
||||||
|
|
||||||
mod servers;
|
mod guilds;
|
||||||
|
|
||||||
pub fn web() -> Scope {
|
pub fn web() -> Scope {
|
||||||
web::scope("/me").service(get).service(update)
|
web::scope("/me")
|
||||||
|
.service(get)
|
||||||
|
.service(update)
|
||||||
|
.service(guilds::get)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("")]
|
#[get("")]
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
use actix_web::{Scope, web};
|
use actix_web::{Scope, web};
|
||||||
|
|
||||||
mod auth;
|
mod auth;
|
||||||
|
mod channels;
|
||||||
mod invites;
|
mod invites;
|
||||||
mod servers;
|
mod guilds;
|
||||||
mod stats;
|
mod stats;
|
||||||
mod users;
|
mod users;
|
||||||
mod me;
|
mod me;
|
||||||
|
@ -14,7 +15,8 @@ pub fn web() -> Scope {
|
||||||
.service(stats::res)
|
.service(stats::res)
|
||||||
.service(auth::web())
|
.service(auth::web())
|
||||||
.service(users::web())
|
.service(users::web())
|
||||||
.service(servers::web())
|
.service(channels::web())
|
||||||
|
.service(guilds::web())
|
||||||
.service(invites::web())
|
.service(invites::web())
|
||||||
.service(me::web())
|
.service(me::web())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
pub mod messages;
|
|
||||||
pub mod socket;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
api::v1::auth::check_access_token, error::Error, structs::{Channel, Member}, utils::{get_auth_header, global_checks}, Data
|
|
||||||
};
|
|
||||||
use actix_web::{HttpRequest, HttpResponse, delete, get, web};
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[get("{uuid}/channels/{channel_uuid}")]
|
|
||||||
pub async fn get(
|
|
||||||
req: HttpRequest,
|
|
||||||
path: web::Path<(Uuid, Uuid)>,
|
|
||||||
data: web::Data<Data>,
|
|
||||||
) -> Result<HttpResponse, Error> {
|
|
||||||
let headers = req.headers();
|
|
||||||
|
|
||||||
let auth_header = get_auth_header(headers)?;
|
|
||||||
|
|
||||||
let (guild_uuid, channel_uuid) = path.into_inner();
|
|
||||||
|
|
||||||
let mut conn = data.pool.get().await?;
|
|
||||||
|
|
||||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
|
||||||
|
|
||||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
|
||||||
|
|
||||||
if let Ok(cache_hit) = data.get_cache_key(format!("{}", channel_uuid)).await {
|
|
||||||
return Ok(HttpResponse::Ok()
|
|
||||||
.content_type("application/json")
|
|
||||||
.body(cache_hit));
|
|
||||||
}
|
|
||||||
|
|
||||||
let channel = Channel::fetch_one(&mut conn, channel_uuid).await?;
|
|
||||||
|
|
||||||
data.set_cache_key(format!("{}", channel_uuid), channel.clone(), 60)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(channel))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[delete("{uuid}/channels/{channel_uuid}")]
|
|
||||||
pub async fn delete(
|
|
||||||
req: HttpRequest,
|
|
||||||
path: web::Path<(Uuid, Uuid)>,
|
|
||||||
data: web::Data<Data>,
|
|
||||||
) -> Result<HttpResponse, Error> {
|
|
||||||
let headers = req.headers();
|
|
||||||
|
|
||||||
let auth_header = get_auth_header(headers)?;
|
|
||||||
|
|
||||||
let (guild_uuid, channel_uuid) = path.into_inner();
|
|
||||||
|
|
||||||
let mut conn = data.pool.get().await?;
|
|
||||||
|
|
||||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
|
||||||
|
|
||||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
|
||||||
|
|
||||||
let channel: Channel;
|
|
||||||
|
|
||||||
if let Ok(cache_hit) = data.get_cache_key(format!("{}", channel_uuid)).await {
|
|
||||||
channel = serde_json::from_str(&cache_hit)?;
|
|
||||||
|
|
||||||
data.del_cache_key(format!("{}", channel_uuid)).await?;
|
|
||||||
} else {
|
|
||||||
channel = Channel::fetch_one(&mut conn, channel_uuid).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.delete(&mut conn).await?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
|
||||||
}
|
|
|
@ -38,7 +38,8 @@ pub struct CacheDatabase {
|
||||||
struct WebBuilder {
|
struct WebBuilder {
|
||||||
ip: Option<String>,
|
ip: Option<String>,
|
||||||
port: Option<u16>,
|
port: Option<u16>,
|
||||||
url: Url,
|
base_path: Option<String>,
|
||||||
|
frontend_url: Url,
|
||||||
_ssl: Option<bool>,
|
_ssl: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +86,8 @@ impl ConfigBuilder {
|
||||||
let web = Web {
|
let web = Web {
|
||||||
ip: self.web.ip.unwrap_or(String::from("0.0.0.0")),
|
ip: self.web.ip.unwrap_or(String::from("0.0.0.0")),
|
||||||
port: self.web.port.unwrap_or(8080),
|
port: self.web.port.unwrap_or(8080),
|
||||||
url: self.web.url,
|
base_path: self.web.base_path.unwrap_or("".to_string()),
|
||||||
|
frontend_url: self.web.frontend_url,
|
||||||
};
|
};
|
||||||
|
|
||||||
let endpoint = match &*self.bunny.endpoint {
|
let endpoint = match &*self.bunny.endpoint {
|
||||||
|
@ -146,7 +148,8 @@ pub struct Config {
|
||||||
pub struct Web {
|
pub struct Web {
|
||||||
pub ip: String,
|
pub ip: String,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub url: Url,
|
pub base_path: String,
|
||||||
|
pub frontend_url: Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -150,7 +150,7 @@ async fn main() -> Result<(), Error> {
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(web::Data::new(data.clone()))
|
.app_data(web::Data::new(data.clone()))
|
||||||
.wrap(cors)
|
.wrap(cors)
|
||||||
.service(api::web())
|
.service(api::web(&data.config.web.base_path))
|
||||||
})
|
})
|
||||||
.bind((web.ip, web.port))?
|
.bind((web.ip, web.port))?
|
||||||
.run()
|
.run()
|
||||||
|
|
|
@ -183,15 +183,26 @@ impl Channel {
|
||||||
futures::future::try_join_all(channel_futures).await
|
futures::future::try_join_all(channel_futures).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_one(conn: &mut Conn, channel_uuid: Uuid) -> Result<Self, Error> {
|
pub async fn fetch_one(data: &Data, channel_uuid: Uuid) -> Result<Self, Error> {
|
||||||
|
if let Ok(cache_hit) = data.get_cache_key(channel_uuid.to_string()).await {
|
||||||
|
return Ok(serde_json::from_str(&cache_hit)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut conn = data.pool.get().await?;
|
||||||
|
|
||||||
use channels::dsl;
|
use channels::dsl;
|
||||||
let channel_builder: ChannelBuilder = dsl::channels
|
let channel_builder: ChannelBuilder = dsl::channels
|
||||||
.filter(dsl::uuid.eq(channel_uuid))
|
.filter(dsl::uuid.eq(channel_uuid))
|
||||||
.select(ChannelBuilder::as_select())
|
.select(ChannelBuilder::as_select())
|
||||||
.get_result(conn)
|
.get_result(&mut conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
channel_builder.build(conn).await
|
let channel = channel_builder.build(&mut conn).await?;
|
||||||
|
|
||||||
|
data.set_cache_key(channel_uuid.to_string(), channel.clone(), 60)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
|
@ -245,19 +256,27 @@ impl Channel {
|
||||||
data.set_cache_key(channel_uuid.to_string(), channel.clone(), 1800)
|
data.set_cache_key(channel_uuid.to_string(), channel.clone(), 1800)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
data.del_cache_key(format!("{}_channels", guild_uuid))
|
if let Ok(_) = data.get_cache_key(format!("{}_channels", guild_uuid)).await {
|
||||||
.await?;
|
data.del_cache_key(format!("{}_channels", guild_uuid))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(channel)
|
Ok(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(self, conn: &mut Conn) -> Result<(), Error> {
|
pub async fn delete(self, data: &Data) -> Result<(), Error> {
|
||||||
|
let mut conn = data.pool.get().await?;
|
||||||
|
|
||||||
use channels::dsl;
|
use channels::dsl;
|
||||||
delete(channels::table)
|
delete(channels::table)
|
||||||
.filter(dsl::uuid.eq(self.uuid))
|
.filter(dsl::uuid.eq(self.uuid))
|
||||||
.execute(conn)
|
.execute(&mut conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
if let Ok(_) = data.get_cache_key(self.uuid.to_string()).await {
|
||||||
|
data.del_cache_key(self.uuid.to_string()).await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,7 +1014,7 @@ impl EmailToken {
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut verify_endpoint = data.config.web.url.join("verify-email")?;
|
let mut verify_endpoint = data.config.web.frontend_url.join("verify-email")?;
|
||||||
|
|
||||||
verify_endpoint.set_query(Some(&format!("token={}", token)));
|
verify_endpoint.set_query(Some(&format!("token={}", token)));
|
||||||
|
|
||||||
|
@ -1085,7 +1104,7 @@ impl PasswordResetToken {
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut reset_endpoint = data.config.web.url.join("reset-password")?;
|
let mut reset_endpoint = data.config.web.frontend_url.join("reset-password")?;
|
||||||
|
|
||||||
reset_endpoint.set_query(Some(&format!("token={}", token)));
|
reset_endpoint.set_query(Some(&format!("token={}", token)));
|
||||||
|
|
||||||
|
@ -1134,7 +1153,7 @@ impl PasswordResetToken {
|
||||||
.get_result(&mut conn)
|
.get_result(&mut conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let login_page = data.config.web.url.join("login")?;
|
let login_page = data.config.web.frontend_url.join("login")?;
|
||||||
|
|
||||||
let email = data
|
let email = data
|
||||||
.mail_client
|
.mail_client
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue