// Mod tables
// TODO eventually do correct expires
- let expires = match data.expires {
- Some(time) => Some(naive_from_unix(time)),
- None => None,
- };
+ let expires = data.expires.map(naive_from_unix);
let form = ModBanFromCommunityForm {
mod_person_id: local_user_view.person.id,
mod post;
mod post_report;
mod private_message;
-pub mod routes;
mod site;
mod websocket;
op: UserOperation,
data: &str,
) -> Result<String, LemmyError> {
- //TODO: handle commented out actions in crud crate
-
match op {
// User ops
- UserOperation::Login => {
- //do_websocket_operation::<Login>(context, id, op, data).await
- todo!()
- }
- UserOperation::Register => {
- //do_websocket_operation::<Register>(context, id, op, data).await
- todo!()
- }
+ UserOperation::Login => do_websocket_operation::<Login>(context, id, op, data).await,
UserOperation::GetCaptcha => do_websocket_operation::<GetCaptcha>(context, id, op, data).await,
- UserOperation::GetPersonDetails => {
- //do_websocket_operation::<GetPersonDetails>(context, id, op, data).await
- todo!()
- }
UserOperation::GetReplies => do_websocket_operation::<GetReplies>(context, id, op, data).await,
UserOperation::AddAdmin => do_websocket_operation::<AddAdmin>(context, id, op, data).await,
UserOperation::BanPerson => do_websocket_operation::<BanPerson>(context, id, op, data).await,
UserOperation::GetPersonMentions => {
- //do_websocket_operation::<GetPersonMentions>(context, id, op, data).await
- todo!()
+ do_websocket_operation::<GetPersonMentions>(context, id, op, data).await
}
UserOperation::MarkPersonMentionAsRead => {
do_websocket_operation::<MarkPersonMentionAsRead>(context, id, op, data).await
UserOperation::MarkAllAsRead => {
do_websocket_operation::<MarkAllAsRead>(context, id, op, data).await
}
- UserOperation::DeleteAccount => {
- //do_websocket_operation::<DeleteAccount>(context, id, op, data).await
- todo!()
- }
UserOperation::PasswordReset => {
do_websocket_operation::<PasswordReset>(context, id, op, data).await
}
}
// Private Message ops
- UserOperation::CreatePrivateMessage => {
- //do_websocket_operation::<CreatePrivateMessage>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditPrivateMessage => {
- //do_websocket_operation::<EditPrivateMessage>(context, id, op, data).await
- todo!()
- }
- UserOperation::DeletePrivateMessage => {
- //do_websocket_operation::<DeletePrivateMessage>(context, id, op, data).await
- todo!()
- }
UserOperation::MarkPrivateMessageAsRead => {
do_websocket_operation::<MarkPrivateMessageAsRead>(context, id, op, data).await
}
- UserOperation::GetPrivateMessages => {
- //do_websocket_operation::<GetPrivateMessages>(context, id, op, data).await
- todo!()
- }
// Site ops
UserOperation::GetModlog => do_websocket_operation::<GetModlog>(context, id, op, data).await,
- UserOperation::CreateSite => {
- //do_websocket_operation::<CreateSite>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditSite => {
- //do_websocket_operation::<EditSite>(context, id, op, data).await
- todo!()
- }
- UserOperation::GetSite => {
- //do_websocket_operation::<GetSite>(context, id, op, data).await
- todo!()
- }
UserOperation::GetSiteConfig => {
do_websocket_operation::<GetSiteConfig>(context, id, op, data).await
}
}
// Community ops
- UserOperation::GetCommunity => {
- //do_websocket_operation::<GetCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::ListCommunities => {
- //do_websocket_operation::<ListCommunities>(context, id, op, data).await
- todo!()
- }
- UserOperation::CreateCommunity => {
- //do_websocket_operation::<CreateCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditCommunity => {
- //do_websocket_operation::<EditCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::DeleteCommunity => {
- //do_websocket_operation::<DeleteCommunity>(context, id, op, data).await
- todo!()
- }
- UserOperation::RemoveCommunity => {
- //do_websocket_operation::<RemoveCommunity>(context, id, op, data).await
- todo!()
- }
UserOperation::FollowCommunity => {
do_websocket_operation::<FollowCommunity>(context, id, op, data).await
}
}
// Post ops
- UserOperation::CreatePost => {
- //do_websocket_operation::<CreatePost>(context, id, op, data).await
- todo!()
- }
- UserOperation::GetPost => {
- //do_websocket_operation::<GetPost>(context, id, op, data).await
- todo!()
- }
- UserOperation::GetPosts => {
- //do_websocket_operation::<GetPosts>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditPost => {
- //do_websocket_operation::<EditPost>(context, id, op, data).await
- todo!()
- }
- UserOperation::DeletePost => {
- //do_websocket_operation::<DeletePost>(context, id, op, data).await
- todo!()
- }
- UserOperation::RemovePost => {
- //do_websocket_operation::<RemovePost>(context, id, op, data).await
- todo!()
- }
UserOperation::LockPost => do_websocket_operation::<LockPost>(context, id, op, data).await,
UserOperation::StickyPost => do_websocket_operation::<StickyPost>(context, id, op, data).await,
UserOperation::CreatePostLike => {
}
// Comment ops
- UserOperation::CreateComment => {
- //do_websocket_operation::<CreateComment>(context, id, op, data).await
- todo!()
- }
- UserOperation::EditComment => {
- //do_websocket_operation::<EditComment>(context, id, op, data).await
- todo!()
- }
- UserOperation::DeleteComment => {
- //do_websocket_operation::<DeleteComment>(context, id, op, data).await
- todo!()
- }
- UserOperation::RemoveComment => {
- //do_websocket_operation::<RemoveComment>(context, id, op, data).await
- todo!()
- }
UserOperation::MarkCommentAsRead => {
do_websocket_operation::<MarkCommentAsRead>(context, id, op, data).await
}
UserOperation::SaveComment => {
do_websocket_operation::<SaveComment>(context, id, op, data).await
}
- UserOperation::GetComments => {
- //do_websocket_operation::<GetComments>(context, id, op, data).await
- todo!()
- }
UserOperation::CreateCommentLike => {
do_websocket_operation::<CreateCommentLike>(context, id, op, data).await
}
#[cfg(test)]
mod tests {
- use crate::{captcha_espeak_wav_base64, check_validator_time};
+ use crate::captcha_espeak_wav_base64;
use lemmy_api_common::check_validator_time;
use lemmy_db_queries::{establish_unpooled_connection, source::local_user::LocalUser_, Crud};
use lemmy_db_schema::source::{
context.chat_server().do_send(captcha_item);
Ok(GetCaptchaResponse {
- ok: Some(CaptchaResponse { png, uuid, wav }),
+ ok: Some(CaptchaResponse { png, wav, uuid }),
})
}
}
}
// Mod tables
- let expires = match data.expires {
- Some(time) => Some(naive_from_unix(time)),
- None => None,
- };
+ let expires = data.expires.map(naive_from_unix);
let form = ModBanForm {
mod_person_id: local_user_view.person.id,
ConnectionId,
LemmyError,
};
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for CreateComment {
};
context.chat_server().do_send(SendComment {
- op: UserOperation::CreateComment,
+ op: UserOperationCrud::CreateComment,
comment: res.clone(),
websocket_id,
});
use lemmy_db_schema::source::{comment::*, moderator::*};
use lemmy_db_views::comment_view::CommentView;
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for DeleteComment {
};
context.chat_server().do_send(SendComment {
- op: UserOperation::DeleteComment,
+ op: UserOperationCrud::DeleteComment,
comment: res.clone(),
websocket_id,
});
};
context.chat_server().do_send(SendComment {
- op: UserOperation::RemoveComment,
+ op: UserOperationCrud::RemoveComment,
comment: res.clone(),
websocket_id,
});
ConnectionId,
LemmyError,
};
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for EditComment {
};
context.chat_server().do_send(SendComment {
- op: UserOperation::EditComment,
+ op: UserOperationCrud::EditComment,
comment: res.clone(),
websocket_id,
});
};
use lemmy_db_views_actor::community_view::CommunityView;
use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{LemmyContext, UserOperation};
+use lemmy_websocket::{LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for DeleteCommunity {
let res = CommunityResponse { community_view };
- send_community_websocket(&res, context, websocket_id, UserOperation::DeleteCommunity);
+ send_community_websocket(
+ &res,
+ context,
+ websocket_id,
+ UserOperationCrud::DeleteCommunity,
+ );
Ok(res)
}
};
// Mod tables
- let expires = match data.expires {
- Some(time) => Some(naive_from_unix(time)),
- None => None,
- };
+ let expires = data.expires.map(naive_from_unix);
let form = ModRemoveCommunityForm {
mod_person_id: local_user_view.person.id,
community_id: data.community_id,
let res = CommunityResponse { community_view };
- send_community_websocket(&res, context, websocket_id, UserOperation::RemoveCommunity);
+ send_community_websocket(
+ &res,
+ context,
+ websocket_id,
+ UserOperationCrud::RemoveCommunity,
+ );
Ok(res)
}
use actix_web::web::Data;
use lemmy_api_common::community::CommunityResponse;
use lemmy_utils::ConnectionId;
-use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperationCrud};
mod create;
mod delete;
res: &CommunityResponse,
context: &Data<LemmyContext>,
websocket_id: Option<ConnectionId>,
- op: UserOperation,
+ op: UserOperationCrud,
) {
// Strip out the person id and subscribed when sending to others
let mut res_sent = res.clone();
let data: &ListCommunities = &self;
let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
- let person_id = match &local_user_view {
- Some(uv) => Some(uv.person.id),
- None => None,
- };
+ let person_id = local_user_view.to_owned().map(|l| l.person.id);
// Don't show NSFW by default
let show_nsfw = match &local_user_view {
ConnectionId,
LemmyError,
};
-use lemmy_websocket::{LemmyContext, UserOperation};
+use lemmy_websocket::{LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for EditCommunity {
let res = CommunityResponse { community_view };
- send_community_websocket(&res, context, websocket_id, UserOperation::EditCommunity);
+ send_community_websocket(
+ &res,
+ context,
+ websocket_id,
+ UserOperationCrud::EditCommunity,
+ );
Ok(res)
}
-use actix_web::web::Data;
+use actix_web::{web, web::Data};
+use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*};
use lemmy_utils::{ConnectionId, LemmyError};
-use lemmy_websocket::LemmyContext;
+use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperationCrud};
+use serde::Deserialize;
mod comment;
mod community;
mod post;
mod private_message;
-pub mod routes;
mod site;
mod user;
websocket_id: Option<ConnectionId>,
) -> Result<Self::Response, LemmyError>;
}
+
+pub async fn match_websocket_operation_crud(
+ context: LemmyContext,
+ id: ConnectionId,
+ op: UserOperationCrud,
+ data: &str,
+) -> Result<String, LemmyError> {
+ //TODO: handle commented out actions in crud crate
+
+ match op {
+ // User ops
+ UserOperationCrud::Register => do_websocket_operation::<Register>(context, id, op, data).await,
+ UserOperationCrud::GetPersonDetails => {
+ do_websocket_operation::<GetPersonDetails>(context, id, op, data).await
+ }
+ UserOperationCrud::DeleteAccount => {
+ do_websocket_operation::<DeleteAccount>(context, id, op, data).await
+ }
+
+ // Private Message ops
+ UserOperationCrud::CreatePrivateMessage => {
+ do_websocket_operation::<CreatePrivateMessage>(context, id, op, data).await
+ }
+ UserOperationCrud::EditPrivateMessage => {
+ do_websocket_operation::<EditPrivateMessage>(context, id, op, data).await
+ }
+ UserOperationCrud::DeletePrivateMessage => {
+ do_websocket_operation::<DeletePrivateMessage>(context, id, op, data).await
+ }
+ UserOperationCrud::GetPrivateMessages => {
+ do_websocket_operation::<GetPrivateMessages>(context, id, op, data).await
+ }
+
+ // Site ops
+ UserOperationCrud::CreateSite => {
+ do_websocket_operation::<CreateSite>(context, id, op, data).await
+ }
+ UserOperationCrud::EditSite => do_websocket_operation::<EditSite>(context, id, op, data).await,
+ UserOperationCrud::GetSite => do_websocket_operation::<GetSite>(context, id, op, data).await,
+
+ // Community ops
+ UserOperationCrud::GetCommunity => {
+ do_websocket_operation::<GetCommunity>(context, id, op, data).await
+ }
+ UserOperationCrud::ListCommunities => {
+ do_websocket_operation::<ListCommunities>(context, id, op, data).await
+ }
+ UserOperationCrud::CreateCommunity => {
+ do_websocket_operation::<CreateCommunity>(context, id, op, data).await
+ }
+ UserOperationCrud::EditCommunity => {
+ do_websocket_operation::<EditCommunity>(context, id, op, data).await
+ }
+ UserOperationCrud::DeleteCommunity => {
+ do_websocket_operation::<DeleteCommunity>(context, id, op, data).await
+ }
+ UserOperationCrud::RemoveCommunity => {
+ do_websocket_operation::<RemoveCommunity>(context, id, op, data).await
+ }
+
+ // Post ops
+ UserOperationCrud::CreatePost => {
+ do_websocket_operation::<CreatePost>(context, id, op, data).await
+ }
+ UserOperationCrud::GetPost => do_websocket_operation::<GetPost>(context, id, op, data).await,
+ UserOperationCrud::GetPosts => do_websocket_operation::<GetPosts>(context, id, op, data).await,
+ UserOperationCrud::EditPost => do_websocket_operation::<EditPost>(context, id, op, data).await,
+ UserOperationCrud::DeletePost => {
+ do_websocket_operation::<DeletePost>(context, id, op, data).await
+ }
+ UserOperationCrud::RemovePost => {
+ do_websocket_operation::<RemovePost>(context, id, op, data).await
+ }
+
+ // Comment ops
+ UserOperationCrud::CreateComment => {
+ do_websocket_operation::<CreateComment>(context, id, op, data).await
+ }
+ UserOperationCrud::EditComment => {
+ do_websocket_operation::<EditComment>(context, id, op, data).await
+ }
+ UserOperationCrud::DeleteComment => {
+ do_websocket_operation::<DeleteComment>(context, id, op, data).await
+ }
+ UserOperationCrud::RemoveComment => {
+ do_websocket_operation::<RemoveComment>(context, id, op, data).await
+ }
+ UserOperationCrud::GetComments => {
+ do_websocket_operation::<GetComments>(context, id, op, data).await
+ }
+ }
+}
+
+async fn do_websocket_operation<'a, 'b, Data>(
+ context: LemmyContext,
+ id: ConnectionId,
+ op: UserOperationCrud,
+ data: &str,
+) -> Result<String, LemmyError>
+where
+ for<'de> Data: Deserialize<'de> + 'a,
+ Data: PerformCrud,
+{
+ let parsed_data: Data = serde_json::from_str(&data)?;
+ let res = parsed_data
+ .perform(&web::Data::new(context), Some(id))
+ .await?;
+ serialize_websocket_message(&op, &res)
+}
ConnectionId,
LemmyError,
};
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for CreatePost {
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::CreatePost,
+ op: UserOperationCrud::CreatePost,
post: res.clone(),
websocket_id,
});
use lemmy_db_schema::source::{moderator::*, post::*};
use lemmy_db_views::post_view::PostView;
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for DeletePost {
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::DeletePost,
+ op: UserOperationCrud::DeletePost,
post: res.clone(),
websocket_id,
});
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::RemovePost,
+ op: UserOperationCrud::RemovePost,
post: res.clone(),
websocket_id,
});
let data: &GetPosts = &self;
let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
- let person_id = match &local_user_view {
- Some(uv) => Some(uv.person.id),
- None => None,
- };
+ let person_id = local_user_view.to_owned().map(|l| l.person.id);
let show_nsfw = match &local_user_view {
Some(uv) => uv.local_user.show_nsfw,
ConnectionId,
LemmyError,
};
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for EditPost {
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::EditPost,
+ op: UserOperationCrud::EditPost,
post: res.clone(),
websocket_id,
});
use lemmy_db_schema::source::private_message::{PrivateMessage, PrivateMessageForm};
use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for CreatePrivateMessage {
let local_recipient_id = local_recipient.local_user.id;
context.chat_server().do_send(SendUserRoomMessage {
- op: UserOperation::CreatePrivateMessage,
+ op: UserOperationCrud::CreatePrivateMessage,
response: res.clone(),
local_recipient_id,
websocket_id,
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for DeletePrivateMessage {
{
let local_recipient_id = local_recipient.local_user.id;
context.chat_server().do_send(SendUserRoomMessage {
- op: UserOperation::DeletePrivateMessage,
+ op: UserOperationCrud::DeletePrivateMessage,
response: res.clone(),
local_recipient_id,
websocket_id,
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for EditPrivateMessage {
{
let local_recipient_id = local_recipient.local_user.id;
context.chat_server().do_send(SendUserRoomMessage {
- op: UserOperation::EditPrivateMessage,
+ op: UserOperationCrud::EditPrivateMessage,
response: res.clone(),
local_recipient_id,
websocket_id,
+++ /dev/null
-use crate::PerformCrud;
-use actix_web::{error::ErrorBadRequest, *};
-use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*};
-use lemmy_utils::rate_limit::RateLimit;
-use lemmy_websocket::LemmyContext;
-use serde::Deserialize;
-
-pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
- cfg
- .service(
- web::scope("/api/v2")
- // Site
- .service(
- web::scope("/site")
- .wrap(rate_limit.message())
- .route("", web::get().to(route_get::<GetSite>))
- // Admin Actions
- .route("", web::post().to(route_post::<CreateSite>))
- .route("", web::put().to(route_post::<EditSite>)),
- )
- // Community
- .service(
- web::resource("/community")
- .guard(guard::Post())
- .wrap(rate_limit.register())
- .route(web::post().to(route_post::<CreateCommunity>)),
- )
- .service(
- web::scope("/community")
- .wrap(rate_limit.message())
- .route("", web::get().to(route_get::<GetCommunity>))
- .route("", web::put().to(route_post::<EditCommunity>))
- .route("/list", web::get().to(route_get::<ListCommunities>))
- .route("/delete", web::post().to(route_post::<DeleteCommunity>))
- // Mod Actions
- .route("/remove", web::post().to(route_post::<RemoveCommunity>)),
- )
- // Post
- .service(
- // Handle POST to /post separately to add the post() rate limitter
- web::resource("/post")
- .guard(guard::Post())
- .wrap(rate_limit.post())
- .route(web::post().to(route_post::<CreatePost>)),
- )
- .service(
- web::scope("/post")
- .wrap(rate_limit.message())
- .route("", web::get().to(route_get::<GetPost>))
- .route("", web::put().to(route_post::<EditPost>))
- .route("/delete", web::post().to(route_post::<DeletePost>))
- .route("/remove", web::post().to(route_post::<RemovePost>))
- .route("/list", web::get().to(route_get::<GetPosts>)),
- )
- // Comment
- .service(
- web::scope("/comment")
- .wrap(rate_limit.message())
- .route("", web::post().to(route_post::<CreateComment>))
- .route("", web::put().to(route_post::<EditComment>))
- .route("/delete", web::post().to(route_post::<DeleteComment>))
- .route("/remove", web::post().to(route_post::<RemoveComment>))
- .route("/list", web::get().to(route_get::<GetComments>)),
- ),
- )
- // Private Message
- .service(
- web::scope("/private_message")
- .wrap(rate_limit.message())
- .route("/list", web::get().to(route_get::<GetPrivateMessages>))
- .route("", web::post().to(route_post::<CreatePrivateMessage>))
- .route("", web::put().to(route_post::<EditPrivateMessage>))
- .route(
- "/delete",
- web::post().to(route_post::<DeletePrivateMessage>),
- ),
- )
- // User
- .service(
- // Account action, I don't like that it's in /user maybe /accounts
- // Handle /user/register separately to add the register() rate limitter
- web::resource("/user/register")
- .guard(guard::Post())
- .wrap(rate_limit.register())
- .route(web::post().to(route_post::<Register>)),
- )
- // User actions
- .service(
- web::scope("/user")
- .wrap(rate_limit.message())
- .route("", web::get().to(route_get::<GetPersonDetails>))
- .route(
- "/delete_account",
- web::post().to(route_post::<DeleteAccount>),
- ),
- );
-}
-
-async fn perform<Request>(
- data: Request,
- context: web::Data<LemmyContext>,
-) -> Result<HttpResponse, Error>
-where
- Request: PerformCrud,
- Request: Send + 'static,
-{
- let res = data
- .perform(&context, None)
- .await
- .map(|json| HttpResponse::Ok().json(json))
- .map_err(ErrorBadRequest)?;
- Ok(res)
-}
-
-async fn route_get<'a, Data>(
- data: web::Query<Data>,
- context: web::Data<LemmyContext>,
-) -> Result<HttpResponse, Error>
-where
- Data: Deserialize<'a> + Send + 'static + PerformCrud,
-{
- perform::<Data>(data.0, context).await
-}
-
-async fn route_post<'a, Data>(
- data: web::Json<Data>,
- context: web::Data<LemmyContext>,
-) -> Result<HttpResponse, Error>
-where
- Data: Deserialize<'a> + Send + 'static + PerformCrud,
-{
- perform::<Data>(data.0, context).await
-}
ConnectionId,
LemmyError,
};
-use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperationCrud};
#[async_trait::async_trait(?Send)]
impl PerformCrud for EditSite {
let res = SiteResponse { site_view };
context.chat_server().do_send(SendAllMessage {
- op: UserOperation::EditSite,
+ op: UserOperationCrud::EditSite,
response: res.clone(),
websocket_id,
});
};
use lemmy_db_views::comment_view::CommentView;
use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation, UserOperationCrud};
pub(crate) async fn receive_create_comment(
create: Create,
};
context.chat_server().do_send(SendComment {
- op: UserOperation::CreateComment,
+ op: UserOperationCrud::CreateComment,
comment: res,
websocket_id: None,
});
};
context.chat_server().do_send(SendComment {
- op: UserOperation::EditComment,
+ op: UserOperationCrud::EditComment,
comment: res,
websocket_id: None,
});
form_id: None,
};
context.chat_server().do_send(SendComment {
- op: UserOperation::EditComment,
+ op: UserOperationCrud::EditComment,
comment: res,
websocket_id: None,
});
form_id: None,
};
context.chat_server().do_send(SendComment {
- op: UserOperation::EditComment,
+ op: UserOperationCrud::EditComment,
comment: res,
websocket_id: None,
});
use lemmy_db_schema::source::comment::{Comment, CommentLike};
use lemmy_db_views::comment_view::CommentView;
use lemmy_utils::LemmyError;
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation, UserOperationCrud};
pub(crate) async fn receive_undo_like_comment(
like: &Like,
};
context.chat_server().do_send(SendComment {
- op: UserOperation::EditComment,
+ op: UserOperationCrud::EditComment,
comment: res,
websocket_id: None,
});
};
context.chat_server().do_send(SendComment {
- op: UserOperation::EditComment,
+ op: UserOperationCrud::EditComment,
comment: res,
websocket_id: None,
});
use lemmy_db_schema::source::community::Community;
use lemmy_db_views_actor::community_view::CommunityView;
use lemmy_utils::LemmyError;
-use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperationCrud};
pub(crate) async fn receive_delete_community(
context: &LemmyContext,
let community_id = res.community_view.community.id;
context.chat_server().do_send(SendCommunityRoomMessage {
- op: UserOperation::EditCommunity,
+ op: UserOperationCrud::EditCommunity,
response: res,
community_id,
websocket_id: None,
let community_id = res.community_view.community.id;
context.chat_server().do_send(SendCommunityRoomMessage {
- op: UserOperation::EditCommunity,
+ op: UserOperationCrud::EditCommunity,
response: res,
community_id,
websocket_id: None,
let community_id = res.community_view.community.id;
context.chat_server().do_send(SendCommunityRoomMessage {
- op: UserOperation::EditCommunity,
+ op: UserOperationCrud::EditCommunity,
response: res,
community_id,
websocket_id: None,
let community_id = res.community_view.community.id;
context.chat_server().do_send(SendCommunityRoomMessage {
- op: UserOperation::EditCommunity,
+ op: UserOperationCrud::EditCommunity,
response: res,
community_id,
websocket_id: None,
};
use lemmy_db_views::post_view::PostView;
use lemmy_utils::{location_info, LemmyError};
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation, UserOperationCrud};
pub(crate) async fn receive_create_post(
create: Create,
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::CreatePost,
+ op: UserOperationCrud::CreatePost,
post: res,
websocket_id: None,
});
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::EditPost,
+ op: UserOperationCrud::EditPost,
post: res,
websocket_id: None,
});
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::EditPost,
+ op: UserOperationCrud::EditPost,
post: res,
websocket_id: None,
});
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::EditPost,
+ op: UserOperationCrud::EditPost,
post: res,
websocket_id: None,
});
use lemmy_db_schema::source::post::{Post, PostLike};
use lemmy_db_views::post_view::PostView;
use lemmy_utils::LemmyError;
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation, UserOperationCrud};
pub(crate) async fn receive_undo_like_post(
like: &Like,
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::EditPost,
+ op: UserOperationCrud::EditPost,
post: res,
websocket_id: None,
});
let res = PostResponse { post_view };
context.chat_server().do_send(SendPost {
- op: UserOperation::EditPost,
+ op: UserOperationCrud::EditPost,
post: res,
websocket_id: None,
});
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
use lemmy_utils::{location_info, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
use url::Url;
pub(crate) async fn receive_create_private_message(
.id;
context.chat_server().do_send(SendUserRoomMessage {
- op: UserOperation::CreatePrivateMessage,
+ op: UserOperationCrud::CreatePrivateMessage,
response: res,
local_recipient_id,
websocket_id: None,
.id;
context.chat_server().do_send(SendUserRoomMessage {
- op: UserOperation::EditPrivateMessage,
+ op: UserOperationCrud::EditPrivateMessage,
response: res,
local_recipient_id,
websocket_id: None,
.id;
context.chat_server().do_send(SendUserRoomMessage {
- op: UserOperation::EditPrivateMessage,
+ op: UserOperationCrud::EditPrivateMessage,
response: res,
local_recipient_id,
websocket_id: None,
.id;
context.chat_server().do_send(SendUserRoomMessage {
- op: UserOperation::EditPrivateMessage,
+ op: UserOperationCrud::EditPrivateMessage,
response: res,
local_recipient_id,
websocket_id: None,
))
.first::<LocalUserViewTuple>(conn)?;
Ok(Self {
+ local_user,
person,
counts,
- local_user,
})
}
))
.first::<LocalUserViewTuple>(conn)?;
Ok(Self {
+ local_user,
person,
counts,
- local_user,
})
}
))
.first::<LocalUserViewTuple>(conn)?;
Ok(Self {
+ local_user,
person,
counts,
- local_user,
})
}
}
))
.first::<LocalUserSettingsViewTuple>(conn)?;
Ok(Self {
+ local_user,
person,
counts,
- local_user,
})
}
}
-use crate::{messages::*, serialize_websocket_message, LemmyContext, UserOperation};
+use crate::{
+ messages::*,
+ serialize_websocket_message,
+ LemmyContext,
+ OperationType,
+ UserOperation,
+ UserOperationCrud,
+};
use actix::prelude::*;
use anyhow::Context as acontext;
use background_jobs::QueueHandle;
data: &str,
) -> Pin<Box<dyn Future<Output = Result<String, LemmyError>> + '_>>;
+type MessageHandlerCrudType = fn(
+ context: LemmyContext,
+ id: ConnectionId,
+ op: UserOperationCrud,
+ data: &str,
+) -> Pin<Box<dyn Future<Output = Result<String, LemmyError>> + '_>>;
+
/// `ChatServer` manages chat rooms and responsible for coordinating chat
/// session.
pub struct ChatServer {
pub(super) captchas: Vec<CaptchaItem>,
message_handler: MessageHandlerType,
+ message_handler_crud: MessageHandlerCrudType,
/// An HTTP Client
client: Client,
pool: Pool<ConnectionManager<PgConnection>>,
rate_limiter: RateLimit,
message_handler: MessageHandlerType,
+ message_handler_crud: MessageHandlerCrudType,
client: Client,
activity_queue: QueueHandle,
) -> ChatServer {
rate_limiter,
captchas: Vec::new(),
message_handler,
+ message_handler_crud,
client,
activity_queue,
}
Ok(())
}
- fn send_post_room_message<Response>(
+ fn send_post_room_message<OP, Response>(
&self,
- op: &UserOperation,
+ op: &OP,
response: &Response,
post_id: PostId,
websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError>
where
+ OP: OperationType + ToString,
Response: Serialize,
{
let res_str = &serialize_websocket_message(op, response)?;
Ok(())
}
- pub fn send_community_room_message<Response>(
+ pub fn send_community_room_message<OP, Response>(
&self,
- op: &UserOperation,
+ op: &OP,
response: &Response,
community_id: CommunityId,
websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError>
where
+ OP: OperationType + ToString,
Response: Serialize,
{
let res_str = &serialize_websocket_message(op, response)?;
Ok(())
}
- pub fn send_mod_room_message<Response>(
+ pub fn send_mod_room_message<OP, Response>(
&self,
- op: &UserOperation,
+ op: &OP,
response: &Response,
community_id: CommunityId,
websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError>
where
+ OP: OperationType + ToString,
Response: Serialize,
{
let res_str = &serialize_websocket_message(op, response)?;
Ok(())
}
- pub fn send_all_message<Response>(
+ pub fn send_all_message<OP, Response>(
&self,
- op: &UserOperation,
+ op: &OP,
response: &Response,
websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError>
where
+ OP: OperationType + ToString,
Response: Serialize,
{
let res_str = &serialize_websocket_message(op, response)?;
Ok(())
}
- pub fn send_user_room_message<Response>(
+ pub fn send_user_room_message<OP, Response>(
&self,
- op: &UserOperation,
+ op: &OP,
response: &Response,
recipient_id: LocalUserId,
websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError>
where
+ OP: OperationType + ToString,
Response: Serialize,
{
let res_str = &serialize_websocket_message(op, response)?;
Ok(())
}
- pub fn send_comment(
+ pub fn send_comment<OP>(
&self,
- user_operation: &UserOperation,
+ user_operation: &OP,
comment: &CommentResponse,
websocket_id: Option<ConnectionId>,
- ) -> Result<(), LemmyError> {
+ ) -> Result<(), LemmyError>
+ where
+ OP: OperationType + ToString,
+ {
let mut comment_reply_sent = comment.clone();
// Strip out my specific user info
Ok(())
}
- pub fn send_post(
+ pub fn send_post<OP>(
&self,
- user_operation: &UserOperation,
+ user_operation: &OP,
post_res: &PostResponse,
websocket_id: Option<ConnectionId>,
- ) -> Result<(), LemmyError> {
+ ) -> Result<(), LemmyError>
+ where
+ OP: OperationType + ToString,
+ {
let community_id = post_res.post_view.community.id;
// Don't send my data with it
client: self.client.to_owned(),
activity_queue: self.activity_queue.to_owned(),
};
+ let message_handler_crud = self.message_handler_crud;
let message_handler = self.message_handler;
async move {
let json: Value = serde_json::from_str(&msg.msg)?;
message: "Unknown op type".to_string(),
})?;
- let user_operation = UserOperation::from_str(&op)?;
- let fut = (message_handler)(context, msg.id, user_operation.clone(), data);
- match user_operation {
- UserOperation::Register => rate_limiter.register().wrap(ip, fut).await,
- UserOperation::CreatePost => rate_limiter.post().wrap(ip, fut).await,
- UserOperation::CreateCommunity => rate_limiter.register().wrap(ip, fut).await,
- _ => rate_limiter.message().wrap(ip, fut).await,
+ if let Ok(user_operation_crud) = UserOperationCrud::from_str(&op) {
+ let fut = (message_handler_crud)(context, msg.id, user_operation_crud.clone(), data);
+ match user_operation_crud {
+ UserOperationCrud::Register => rate_limiter.register().wrap(ip, fut).await,
+ UserOperationCrud::CreatePost => rate_limiter.post().wrap(ip, fut).await,
+ UserOperationCrud::CreateCommunity => rate_limiter.register().wrap(ip, fut).await,
+ _ => rate_limiter.message().wrap(ip, fut).await,
+ }
+ } else {
+ let user_operation = UserOperation::from_str(&op)?;
+ let fut = (message_handler)(context, msg.id, user_operation.clone(), data);
+ rate_limiter.message().wrap(ip, fut).await
}
}
}
use crate::{
chat_server::{ChatServer, SessionInfo},
messages::*,
+ OperationType,
};
use actix::{Actor, Context, Handler, ResponseFuture};
use lemmy_db_schema::naive_now;
}
}
-impl<Response> Handler<SendAllMessage<Response>> for ChatServer
+impl<OP, Response> Handler<SendAllMessage<OP, Response>> for ChatServer
where
+ OP: OperationType + ToString,
Response: Serialize,
{
type Result = ();
- fn handle(&mut self, msg: SendAllMessage<Response>, _: &mut Context<Self>) {
+ fn handle(&mut self, msg: SendAllMessage<OP, Response>, _: &mut Context<Self>) {
self
.send_all_message(&msg.op, &msg.response, msg.websocket_id)
.ok();
}
}
-impl<Response> Handler<SendUserRoomMessage<Response>> for ChatServer
+impl<OP, Response> Handler<SendUserRoomMessage<OP, Response>> for ChatServer
where
+ OP: OperationType + ToString,
Response: Serialize,
{
type Result = ();
- fn handle(&mut self, msg: SendUserRoomMessage<Response>, _: &mut Context<Self>) {
+ fn handle(&mut self, msg: SendUserRoomMessage<OP, Response>, _: &mut Context<Self>) {
self
.send_user_room_message(
&msg.op,
}
}
-impl<Response> Handler<SendCommunityRoomMessage<Response>> for ChatServer
+impl<OP, Response> Handler<SendCommunityRoomMessage<OP, Response>> for ChatServer
where
+ OP: OperationType + ToString,
Response: Serialize,
{
type Result = ();
- fn handle(&mut self, msg: SendCommunityRoomMessage<Response>, _: &mut Context<Self>) {
+ fn handle(&mut self, msg: SendCommunityRoomMessage<OP, Response>, _: &mut Context<Self>) {
self
.send_community_room_message(&msg.op, &msg.response, msg.community_id, msg.websocket_id)
.ok();
}
}
-impl Handler<SendPost> for ChatServer {
+impl<OP> Handler<SendPost<OP>> for ChatServer
+where
+ OP: OperationType + ToString,
+{
type Result = ();
- fn handle(&mut self, msg: SendPost, _: &mut Context<Self>) {
+ fn handle(&mut self, msg: SendPost<OP>, _: &mut Context<Self>) {
self.send_post(&msg.op, &msg.post, msg.websocket_id).ok();
}
}
-impl Handler<SendComment> for ChatServer {
+impl<OP> Handler<SendComment<OP>> for ChatServer
+where
+ OP: OperationType + ToString,
+{
type Result = ();
- fn handle(&mut self, msg: SendComment, _: &mut Context<Self>) {
+ fn handle(&mut self, msg: SendComment<OP>, _: &mut Context<Self>) {
self
.send_comment(&msg.op, &msg.comment, msg.websocket_id)
.ok();
data: T,
}
-pub fn serialize_websocket_message<Response>(
- op: &UserOperation,
+pub fn serialize_websocket_message<OP, Response>(
+ op: &OP,
data: &Response,
) -> Result<String, LemmyError>
where
Response: Serialize,
+ OP: ToString,
{
let response = WebsocketResponse {
op: op.to_string(),
#[derive(EnumString, ToString, Debug, Clone)]
pub enum UserOperation {
Login,
- Register,
GetCaptcha,
- CreateCommunity,
- CreatePost,
- ListCommunities,
- GetPost,
- GetCommunity,
- CreateComment,
- EditComment,
- DeleteComment,
- RemoveComment,
MarkCommentAsRead,
SaveComment,
CreateCommentLike,
CreateCommentReport,
ResolveCommentReport,
ListCommentReports,
- GetPosts,
CreatePostLike,
- EditPost,
- DeletePost,
- RemovePost,
LockPost,
StickyPost,
SavePost,
ResolvePostReport,
ListPostReports,
GetReportCount,
- EditCommunity,
- DeleteCommunity,
- RemoveCommunity,
FollowCommunity,
GetFollowedCommunities,
- GetPersonDetails,
GetReplies,
GetPersonMentions,
MarkPersonMentionAsRead,
GetModlog,
BanFromCommunity,
AddModToCommunity,
- CreateSite,
- EditSite,
- GetSite,
AddAdmin,
BanPerson,
Search,
SaveUserSettings,
TransferCommunity,
TransferSite,
- DeleteAccount,
PasswordReset,
PasswordChange,
- CreatePrivateMessage,
- EditPrivateMessage,
- DeletePrivateMessage,
MarkPrivateMessageAsRead,
- GetPrivateMessages,
UserJoin,
- GetComments,
GetSiteConfig,
SaveSiteConfig,
PostJoin,
CommunityJoin,
ModJoin,
}
+
+#[derive(EnumString, ToString, Debug, Clone)]
+pub enum UserOperationCrud {
+ // Site
+ CreateSite,
+ GetSite,
+ EditSite,
+ // Community
+ CreateCommunity,
+ ListCommunities,
+ GetCommunity,
+ EditCommunity,
+ DeleteCommunity,
+ RemoveCommunity,
+ // Post
+ CreatePost,
+ GetPost,
+ GetPosts,
+ EditPost,
+ DeletePost,
+ RemovePost,
+ // Comment
+ CreateComment,
+ GetComments,
+ EditComment,
+ DeleteComment,
+ RemoveComment,
+ // User
+ Register,
+ GetPersonDetails,
+ DeleteAccount,
+ // Private Message
+ CreatePrivateMessage,
+ GetPrivateMessages,
+ EditPrivateMessage,
+ DeletePrivateMessage,
+}
+
+pub trait OperationType {}
+
+impl OperationType for UserOperationCrud {}
+
+impl OperationType for UserOperation {}
#[derive(Message)]
#[rtype(result = "()")]
-pub struct SendAllMessage<Response> {
- pub op: UserOperation,
+pub struct SendAllMessage<OP: ToString, Response> {
+ pub op: OP,
pub response: Response,
pub websocket_id: Option<ConnectionId>,
}
#[derive(Message)]
#[rtype(result = "()")]
-pub struct SendUserRoomMessage<Response> {
- pub op: UserOperation,
+pub struct SendUserRoomMessage<OP: ToString, Response> {
+ pub op: OP,
pub response: Response,
pub local_recipient_id: LocalUserId,
pub websocket_id: Option<ConnectionId>,
#[derive(Message)]
#[rtype(result = "()")]
-pub struct SendCommunityRoomMessage<Response> {
- pub op: UserOperation,
+pub struct SendCommunityRoomMessage<OP: ToString, Response> {
+ pub op: OP,
pub response: Response,
pub community_id: CommunityId,
pub websocket_id: Option<ConnectionId>,
#[derive(Message)]
#[rtype(result = "()")]
-pub struct SendPost {
- pub op: UserOperation,
+pub struct SendPost<OP: ToString> {
+ pub op: OP,
pub post: PostResponse,
pub websocket_id: Option<ConnectionId>,
}
#[derive(Message)]
#[rtype(result = "()")]
-pub struct SendComment {
- pub op: UserOperation,
+pub struct SendComment<OP: ToString> {
+ pub op: OP,
pub comment: CommentResponse,
pub websocket_id: Option<ConnectionId>,
}
/// How long before lack of client response causes a timeout
const CLIENT_TIMEOUT: Duration = Duration::from_secs(10);
+pub fn config(cfg: &mut web::ServiceConfig) {
+ cfg.service(web::resource("/ws").to(chat_route));
+}
+
/// Entry point for our route
-pub async fn chat_route(
+async fn chat_route(
req: HttpRequest,
stream: web::Payload,
context: web::Data<LemmyContext>,
- ./volumes/pictrs_alpha:/mnt
lemmy-alpha-ui:
- image: dessalines/lemmy-ui:0.9.9
+ image: dessalines/lemmy-ui:0.10.0-rc.12
environment:
- LEMMY_INTERNAL_HOST=lemmy-alpha:8541
- LEMMY_EXTERNAL_HOST=localhost:8541
-use crate::Perform;
use actix_web::{error::ErrorBadRequest, *};
+use lemmy_api::Perform;
use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*, websocket::*};
+use lemmy_api_crud::PerformCrud;
use lemmy_utils::rate_limit::RateLimit;
-use lemmy_websocket::{routes::chat_route, LemmyContext};
+use lemmy_websocket::LemmyContext;
use serde::Deserialize;
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
cfg.service(
web::scope("/api/v2")
- // Websockets
- .service(web::resource("/ws").to(chat_route))
// Site
.service(
web::scope("/site")
.wrap(rate_limit.message())
+ .route("", web::get().to(route_get_crud::<GetSite>))
// Admin Actions
+ .route("", web::post().to(route_post_crud::<CreateSite>))
+ .route("", web::put().to(route_post_crud::<EditSite>))
.route("/transfer", web::post().to(route_post::<TransferSite>))
.route("/config", web::get().to(route_get::<GetSiteConfig>))
.route("/config", web::put().to(route_post::<SaveSiteConfig>)),
.route(web::get().to(route_get::<Search>)),
)
// Community
+ .service(
+ web::resource("/community")
+ .guard(guard::Post())
+ .wrap(rate_limit.register())
+ .route(web::post().to(route_post_crud::<CreateCommunity>)),
+ )
.service(
web::scope("/community")
.wrap(rate_limit.message())
+ .route("", web::get().to(route_get_crud::<GetCommunity>))
+ .route("", web::put().to(route_post_crud::<EditCommunity>))
+ .route("/list", web::get().to(route_get_crud::<ListCommunities>))
.route("/follow", web::post().to(route_post::<FollowCommunity>))
+ .route(
+ "/delete",
+ web::post().to(route_post_crud::<DeleteCommunity>),
+ )
+ // Mod Actions
+ .route(
+ "/remove",
+ web::post().to(route_post_crud::<RemoveCommunity>),
+ )
.route("/transfer", web::post().to(route_post::<TransferCommunity>))
.route("/ban_user", web::post().to(route_post::<BanFromCommunity>))
.route("/mod", web::post().to(route_post::<AddModToCommunity>))
.route("/mod/join", web::post().to(route_post::<ModJoin>)),
)
// Post
+ .service(
+ // Handle POST to /post separately to add the post() rate limitter
+ web::resource("/post")
+ .guard(guard::Post())
+ .wrap(rate_limit.post())
+ .route(web::post().to(route_post_crud::<CreatePost>)),
+ )
.service(
web::scope("/post")
.wrap(rate_limit.message())
+ .route("", web::get().to(route_get_crud::<GetPost>))
+ .route("", web::put().to(route_post_crud::<EditPost>))
+ .route("/delete", web::post().to(route_post_crud::<DeletePost>))
+ .route("/remove", web::post().to(route_post_crud::<RemovePost>))
.route("/lock", web::post().to(route_post::<LockPost>))
.route("/sticky", web::post().to(route_post::<StickyPost>))
+ .route("/list", web::get().to(route_get_crud::<GetPosts>))
.route("/like", web::post().to(route_post::<CreatePostLike>))
.route("/save", web::put().to(route_post::<SavePost>))
.route("/join", web::post().to(route_post::<PostJoin>))
.service(
web::scope("/comment")
.wrap(rate_limit.message())
+ .route("", web::post().to(route_post_crud::<CreateComment>))
+ .route("", web::put().to(route_post_crud::<EditComment>))
+ .route("/delete", web::post().to(route_post_crud::<DeleteComment>))
+ .route("/remove", web::post().to(route_post_crud::<RemoveComment>))
.route(
"/mark_as_read",
web::post().to(route_post::<MarkCommentAsRead>),
)
.route("/like", web::post().to(route_post::<CreateCommentLike>))
.route("/save", web::put().to(route_post::<SaveComment>))
+ .route("/list", web::get().to(route_get_crud::<GetComments>))
.route("/report", web::post().to(route_post::<CreateCommentReport>))
.route(
"/report/resolve",
.service(
web::scope("/private_message")
.wrap(rate_limit.message())
+ .route("/list", web::get().to(route_get_crud::<GetPrivateMessages>))
+ .route("", web::post().to(route_post_crud::<CreatePrivateMessage>))
+ .route("", web::put().to(route_post_crud::<EditPrivateMessage>))
+ .route(
+ "/delete",
+ web::post().to(route_post_crud::<DeletePrivateMessage>),
+ )
.route(
"/mark_as_read",
web::post().to(route_post::<MarkPrivateMessageAsRead>),
),
)
+ // User
+ .service(
+ // Account action, I don't like that it's in /user maybe /accounts
+ // Handle /user/register separately to add the register() rate limitter
+ web::resource("/user/register")
+ .guard(guard::Post())
+ .wrap(rate_limit.register())
+ .route(web::post().to(route_post_crud::<Register>)),
+ )
// User actions
.service(
web::scope("/user")
.wrap(rate_limit.message())
+ .route("", web::get().to(route_get_crud::<GetPersonDetails>))
.route("/mention", web::get().to(route_get::<GetPersonMentions>))
.route(
"/mention/mark_as_read",
// Account actions. I don't like that they're in /user maybe /accounts
.route("/login", web::post().to(route_post::<Login>))
.route("/get_captcha", web::get().to(route_get::<GetCaptcha>))
+ .route(
+ "/delete_account",
+ web::post().to(route_post_crud::<DeleteAccount>),
+ )
.route(
"/password_reset",
web::post().to(route_post::<PasswordReset>),
{
perform::<Data>(data.0, context).await
}
+
+async fn perform_crud<Request>(
+ data: Request,
+ context: web::Data<LemmyContext>,
+) -> Result<HttpResponse, Error>
+where
+ Request: PerformCrud,
+ Request: Send + 'static,
+{
+ let res = data
+ .perform(&context, None)
+ .await
+ .map(|json| HttpResponse::Ok().json(json))
+ .map_err(ErrorBadRequest)?;
+ Ok(res)
+}
+
+async fn route_get_crud<'a, Data>(
+ data: web::Query<Data>,
+ context: web::Data<LemmyContext>,
+) -> Result<HttpResponse, Error>
+where
+ Data: Deserialize<'a> + Send + 'static + PerformCrud,
+{
+ perform_crud::<Data>(data.0, context).await
+}
+
+async fn route_post_crud<'a, Data>(
+ data: web::Json<Data>,
+ context: web::Data<LemmyContext>,
+) -> Result<HttpResponse, Error>
+where
+ Data: Deserialize<'a> + Send + 'static + PerformCrud,
+{
+ perform_crud::<Data>(data.0, context).await
+}
#![recursion_limit = "512"]
+pub mod api_routes;
pub mod code_migrations;
pub mod scheduled_tasks;
};
use lemmy_api::match_websocket_operation;
use lemmy_api_common::blocking;
+use lemmy_api_crud::match_websocket_operation_crud;
use lemmy_apub::activity_queue::create_activity_queue;
use lemmy_db_queries::get_database_url_from_env;
use lemmy_routes::{feeds, images, nodeinfo, webfinger};
-use lemmy_server::{code_migrations::run_advanced_migrations, scheduled_tasks};
+use lemmy_server::{api_routes, code_migrations::run_advanced_migrations, scheduled_tasks};
use lemmy_utils::{
rate_limit::{rate_limiter::RateLimiter, RateLimit},
settings::structs::Settings,
pool.clone(),
rate_limiter.clone(),
|c, i, o, d| Box::pin(match_websocket_operation(c, i, o, d)),
+ |c, i, o, d| Box::pin(match_websocket_operation_crud(c, i, o, d)),
Client::default(),
activity_queue.clone(),
)
.wrap(middleware::Logger::default())
.data(context)
// The routes
- .configure(|cfg| lemmy_api_crud::routes::config(cfg, &rate_limiter))
- .configure(|cfg| lemmy_api::routes::config(cfg, &rate_limiter))
+ .configure(|cfg| api_routes::config(cfg, &rate_limiter))
+ .configure(lemmy_websocket::routes::config)
.configure(lemmy_apub::routes::config)
.configure(feeds::config)
.configure(|cfg| images::config(cfg, &rate_limiter))