use crate::{ api::{comment::*, community::*, post::*, site::*, user::*, Oper, Perform}, rate_limit::RateLimit, routes::{ChatServerParam, DbPoolParam}, websocket::WebsocketInfo, }; use actix_web::{client::Client, error::ErrorBadRequest, *}; use serde::Serialize; pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { cfg.service( web::scope("/api/v1") // Websockets .service(web::resource("/ws").to(super::websocket::chat_route)) // Site .service( web::scope("/site") .wrap(rate_limit.message()) .route("", web::get().to(route_get::)) // Admin Actions .route("", web::post().to(route_post::)) .route("", web::put().to(route_post::)) .route("/transfer", web::post().to(route_post::)) .route("/config", web::get().to(route_get::)) .route("/config", web::put().to(route_post::)), ) .service( web::resource("/categories") .wrap(rate_limit.message()) .route(web::get().to(route_get::)), ) .service( web::resource("/modlog") .wrap(rate_limit.message()) .route(web::get().to(route_get::)), ) .service( web::resource("/search") .wrap(rate_limit.message()) .route(web::get().to(route_get::)), ) // Community .service( web::resource("/community") .guard(guard::Post()) .wrap(rate_limit.register()) .route(web::post().to(route_post::)), ) .service( web::scope("/community") .wrap(rate_limit.message()) .route("", web::get().to(route_get::)) .route("", web::put().to(route_post::)) .route("/list", web::get().to(route_get::)) .route("/follow", web::post().to(route_post::)) // Mod Actions .route("/transfer", web::post().to(route_post::)) .route("/ban_user", web::post().to(route_post::)) .route("/mod", web::post().to(route_post::)), ) // 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::)), ) .service( web::scope("/post") .wrap(rate_limit.message()) .route("", web::get().to(route_get::)) .route("", web::put().to(route_post::)) .route("/list", web::get().to(route_get::)) .route("/like", web::post().to(route_post::)) .route("/save", web::put().to(route_post::)), ) // Comment .service( web::scope("/comment") .wrap(rate_limit.message()) .route("", web::post().to(route_post::)) .route("", web::put().to(route_post::)) .route("/like", web::post().to(route_post::)) .route("/save", web::put().to(route_post::)), ) // Private Message .service( web::scope("/private_message") .wrap(rate_limit.message()) .route("/list", web::get().to(route_get::)) .route("", web::post().to(route_post::)) .route("", web::put().to(route_post::)), ) // 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::)), ) // User actions .service( web::scope("/user") .wrap(rate_limit.message()) .route("", web::get().to(route_get::)) .route("/mention", web::get().to(route_get::)) .route("/mention", web::put().to(route_post::)) .route("/replies", web::get().to(route_get::)) .route( "/followed_communities", web::get().to(route_get::), ) // Admin action. I don't like that it's in /user .route("/ban", web::post().to(route_post::)) // Account actions. I don't like that they're in /user maybe /accounts .route("/login", web::post().to(route_post::)) .route( "/delete_account", web::post().to(route_post::), ) .route( "/password_reset", web::post().to(route_post::), ) .route( "/password_change", web::post().to(route_post::), ) // mark_all_as_read feels off being in this section as well .route( "/mark_all_as_read", web::post().to(route_post::), ) .route( "/save_user_settings", web::put().to(route_post::), ), ) // Admin Actions .service( web::resource("/admin/add") .wrap(rate_limit.message()) .route(web::post().to(route_post::)), ), ); } async fn perform( data: Request, client: &Client, db: DbPoolParam, chat_server: ChatServerParam, ) -> Result where Oper: Perform, Request: Send + 'static, { let ws_info = WebsocketInfo { chatserver: chat_server.get_ref().to_owned(), id: None, }; let oper: Oper = Oper::new(data, client.clone()); let res = oper .perform(&db, Some(ws_info)) .await .map(|json| HttpResponse::Ok().json(json)) .map_err(ErrorBadRequest)?; Ok(res) } async fn route_get( data: web::Query, client: web::Data, db: DbPoolParam, chat_server: ChatServerParam, ) -> Result where Data: Serialize + Send + 'static, Oper: Perform, { perform::(data.0, &client, db, chat_server).await } async fn route_post( data: web::Json, client: web::Data, db: DbPoolParam, chat_server: ChatServerParam, ) -> Result where Data: Serialize + Send + 'static, Oper: Perform, { perform::(data.0, &client, db, chat_server).await }