use std::error::Error; use crate::controllers::{account_controller, comments_controller, conversations_controller, forez_controller, friends_controller, groups_controller, likes_controller, notifications_controller, posts_controller, push_notifications_controller, search_controller, server_controller, settings_controller, surveys_controller, user_controller, user_ws_controller, virtual_directory_controller, web_app_controller}; use crate::controllers::admin::*; use crate::data::http_request_handler::HttpRequestHandler; use crate::routes::Method::{GET, POST}; /// Project routes /// /// @author Pierre Hubert #[derive(PartialEq)] pub enum Method { GET, POST, } /// Limitation policy of a request for a given IP address /// /// All the limit are on a per-hour basis (the first request that triggers the limit is the one /// that is recorded) pub enum LimitPolicy { // No limit is applied to the request NONE, // An acceptable threshold of successful requests (= 200) is defined, then the requests are // rejected (they are not even processed) SUCCESS(u64), // An acceptable threshold of unsuccessful requests (!= 200) is defined, then the requests are // rejected (they are not even processed) FAILURE(u64), // An acceptable threshold of request (successful or unsuccessful) is defined then the requests // are rejected (they are not even processed) ANY(u64), } /// Scope of the route pub enum RouteScope { // Route accessible by a "normal" user of Comunic USER, // Route accessible by an administrator of Comunic ADMIN, } impl LimitPolicy { pub fn is_none(&self) -> bool { matches!(self, LimitPolicy::NONE) } pub fn get_count(&self) -> u64 { match self { LimitPolicy::NONE => 0, LimitPolicy::SUCCESS(n) => n.clone(), LimitPolicy::FAILURE(n) => n.clone(), LimitPolicy::ANY(n) => n.clone(), } } } /// Define types pub type RequestResult = Result<(), Box>; pub type RequestProcess = Box RequestResult>; pub struct Route { /// Route scope pub scope: RouteScope, /// The Verb used for the request pub method: Method, /// The URI of the request, with the leading "/" pub uri: &'static str, /// If set to true, unauthenticated requests will be rejected pub need_login: bool, /// The function called to process a request pub func: RequestProcess, /// Request rate policy pub limit_policy: LimitPolicy, } impl Route { pub fn get_without_login(uri: &'static str, func: RequestProcess) -> Route { Route { scope: RouteScope::USER, method: GET, need_login: false, uri, func, limit_policy: LimitPolicy::NONE, } } pub fn post_without_login(uri: &'static str, func: RequestProcess) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: false, uri, func, limit_policy: LimitPolicy::NONE, } } pub fn limited_post_without_login(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: false, uri, func, limit_policy, } } pub fn post(uri: &'static str, func: RequestProcess) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: true, uri, func, limit_policy: LimitPolicy::NONE, } } pub fn limited_post(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: true, uri, func, limit_policy, } } pub fn limited_admin_post_without_login(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route { Route { scope: RouteScope::ADMIN, method: POST, need_login: false, uri, func, limit_policy, } } pub fn admin_post(uri: &'static str, func: RequestProcess) -> Route { Route { scope: RouteScope::ADMIN, method: POST, need_login: true, uri, func, limit_policy: LimitPolicy::NONE, } } } /// Get the list of routes available pub fn get_routes() -> Vec { vec![ // Server meta routes Route::get_without_login("/", Box::new(server_controller::main_index)), Route::post_without_login("/server/config", Box::new(server_controller::get_config)), // Main user WebSocket Route::post("/ws/token", Box::new(user_ws_controller::get_token)), // Account controller Route::limited_post_without_login("/account/create", Box::new(account_controller::create), LimitPolicy::SUCCESS(10)), Route::limited_post_without_login("/account/login", Box::new(account_controller::login_user), LimitPolicy::FAILURE(10)), Route::post("/account/logout", Box::new(account_controller::logout_user)), Route::post("/account/disconnect_all_devices", Box::new(account_controller::disconnect_all_devices)), Route::post("/account/id", Box::new(account_controller::user_id)), Route::post("/account/mail", Box::new(account_controller::get_mail)), Route::limited_post_without_login("/account/exists_email", Box::new(account_controller::exists_mail), LimitPolicy::ANY(30)), Route::limited_post_without_login("/account/has_security_questions", Box::new(account_controller::has_security_questions), LimitPolicy::FAILURE(10)), Route::limited_post_without_login("/account/get_security_questions", Box::new(account_controller::get_security_questions), LimitPolicy::FAILURE(10)), Route::limited_post_without_login("/account/check_security_answers", Box::new(account_controller::check_security_answers), LimitPolicy::FAILURE(10)), Route::limited_post_without_login("/account/check_password_reset_token", Box::new(account_controller::check_password_reset_token), LimitPolicy::FAILURE(10)), Route::limited_post_without_login("/account/reset_user_passwd", Box::new(account_controller::reset_user_password), LimitPolicy::FAILURE(10)), Route::limited_post("/account/export_data", Box::new(account_controller::export_data), LimitPolicy::ANY(10)), Route::post("/account/delete", Box::new(account_controller::delete_account)), // User controller Route::post("/user/getInfo", Box::new(user_controller::get_single)), Route::post("/user/getInfos", Box::new(user_controller::get_single)), Route::post("/user/getInfoMultiple", Box::new(user_controller::get_multiple)), Route::post("/user/getInfosMultiple", Box::new(user_controller::get_multiple)), Route::post("/user/getAdvancedUserInfo", Box::new(user_controller::get_advanced_info)), Route::post("/user/getAdvancedUserInfos", Box::new(user_controller::get_advanced_info)), // Settings controller Route::post("/settings/get_general", Box::new(settings_controller::get_general)), Route::post("/settings/set_general", Box::new(settings_controller::set_general)), Route::post("/settings/check_user_directory_availability", Box::new(settings_controller::check_virtual_directory)), Route::post("/settings/get_language", Box::new(settings_controller::get_language)), Route::post("/settings/set_language", Box::new(settings_controller::set_language)), Route::post("/settings/get_security", Box::new(settings_controller::get_security)), Route::post("/settings/set_security", Box::new(settings_controller::set_security)), Route::post("/settings/check_password", Box::new(settings_controller::check_password)), Route::post("/settings/update_password", Box::new(settings_controller::update_password)), Route::post("/settings/get_account_image", Box::new(settings_controller::get_account_image_settings)), Route::post("/settings/upload_account_image", Box::new(settings_controller::upload_account_image)), Route::post("/settings/delete_account_image", Box::new(settings_controller::delete_account_image)), Route::post("/settings/set_account_image_visibility", Box::new(settings_controller::set_account_image_visibility)), Route::post("/settings/upload_custom_emoji", Box::new(settings_controller::upload_custom_emoji)), Route::post("/settings/delete_custom_emoji", Box::new(settings_controller::delete_custom_emoji)), Route::post("/settings/get_data_conservation_policy", Box::new(settings_controller::get_data_conservation_policy)), Route::limited_post("/settings/set_data_conservation_policy", Box::new(settings_controller::set_data_conservation_policy), LimitPolicy::FAILURE(10)), Route::post("/settings/get_notifications", Box::new(settings_controller::get_notifications)), Route::post("/settings/set_notifications", Box::new(settings_controller::set_notifications)), // Push notifications controller Route::post("/push_notifications/status", Box::new(push_notifications_controller::get_status)), Route::post("/push_notifications/configure", Box::new(push_notifications_controller::configure)), // Friends controller Route::post("/friends/getList", Box::new(friends_controller::get_list)), Route::post("/friends/get_single_infos", Box::new(friends_controller::get_single_friendship_info)), Route::post("/friends/get_user_list", Box::new(friends_controller::get_other_user_list)), Route::post("/friends/getStatus", Box::new(friends_controller::get_status)), Route::post("/friends/sendRequest", Box::new(friends_controller::send_request)), Route::post("/friends/removeRequest", Box::new(friends_controller::cancel_request)), Route::post("/friends/respondRequest", Box::new(friends_controller::respond_request)), Route::post("/friends/remove", Box::new(friends_controller::remove_friend)), Route::post("/friends/setFollowing", Box::new(friends_controller::set_following)), Route::post("/friends/set_can_post_texts", Box::new(friends_controller::set_can_post_texts)), // Conversations controller Route::post("/conversations/create", Box::new(conversations_controller::create)), Route::post("/conversations/getList", Box::new(conversations_controller::get_list)), Route::post("/conversations/get_single", Box::new(conversations_controller::get_single)), Route::post("/conversations/updateSettings", Box::new(conversations_controller::update_settings)), Route::post("/conversations/change_image", Box::new(conversations_controller::change_image)), Route::post("/conversations/delete_image", Box::new(conversations_controller::delete_image)), Route::post("/conversations/addMember", Box::new(conversations_controller::add_member)), Route::post("/conversations/setAdmin", Box::new(conversations_controller::set_admin)), Route::post("/conversations/removeMember", Box::new(conversations_controller::remove_member)), Route::post("/conversations/getPrivate", Box::new(conversations_controller::find_private)), Route::post("/conversations/refresh_single", Box::new(conversations_controller::refresh_single)), Route::post("/conversations/get_older_messages", Box::new(conversations_controller::get_older_messages)), Route::post("/conversations/sendMessage", Box::new(conversations_controller::send_message)), Route::post("/conversations/get_number_unread", Box::new(conversations_controller::count_unread)), Route::post("/conversations/get_list_unread", Box::new(conversations_controller::list_unread)), Route::post("/conversations/delete", Box::new(conversations_controller::delete_conversation)), Route::post("/conversations/updateMessage", Box::new(conversations_controller::update_message)), Route::post("/conversations/deleteMessage", Box::new(conversations_controller::delete_message)), // Search controller Route::post("/search/user", Box::new(search_controller::search_user)), Route::post("/user/search", Box::new(search_controller::search_user)), Route::post("/search/global", Box::new(search_controller::search_global)), // Groups controller Route::post("/groups/create", Box::new(groups_controller::create)), Route::post("/groups/get_my_list", Box::new(groups_controller::get_list_user)), Route::post("/groups/get_info", Box::new(groups_controller::get_info_single)), Route::post("/groups/get_multiple_info", Box::new(groups_controller::get_info_multiple)), Route::post("/groups/get_advanced_info", Box::new(groups_controller::get_advanced_info)), Route::post("/groups/get_settings", Box::new(groups_controller::get_settings)), Route::post("/groups/set_settings", Box::new(groups_controller::set_settings)), Route::post("/groups/checkVirtualDirectory", Box::new(groups_controller::check_virtual_dir)), Route::post("/groups/upload_logo", Box::new(groups_controller::upload_logo)), Route::post("/groups/delete_logo", Box::new(groups_controller::delete_logo)), Route::post("/groups/create_conversation", Box::new(groups_controller::create_conversation)), Route::post("/groups/set_conversation_visibility", Box::new(groups_controller::set_conversation_visibility)), Route::post("/groups/delete_conversation", Box::new(groups_controller::delete_conversation)), Route::post("/groups/get_members", Box::new(groups_controller::get_members)), Route::post("/groups/invite", Box::new(groups_controller::invite_user)), Route::post("/groups/cancel_invitation", Box::new(groups_controller::cancel_invitation)), Route::post("/groups/respond_invitation", Box::new(groups_controller::respond_invitation)), Route::post("/groups/send_request", Box::new(groups_controller::send_request)), Route::post("/groups/cancel_request", Box::new(groups_controller::cancel_request)), Route::post("/groups/delete_member", Box::new(groups_controller::delete_member)), Route::post("/groups/update_membership_level", Box::new(groups_controller::update_membership)), Route::post("/groups/respond_request", Box::new(groups_controller::respond_request)), Route::post("/groups/get_membership", Box::new(groups_controller::get_membership)), Route::post("/groups/remove_membership", Box::new(groups_controller::remove_membership)), Route::post("/groups/set_following", Box::new(groups_controller::set_following)), Route::limited_post("/groups/delete", Box::new(groups_controller::delete_group), LimitPolicy::FAILURE(10)), // Posts controller Route::post("/posts/get_user", Box::new(posts_controller::get_list_user)), Route::post("/posts/get_group", Box::new(posts_controller::get_list_group)), Route::post("/posts/get_latest", Box::new(posts_controller::get_latest)), Route::post("/posts/get_single", Box::new(posts_controller::get_single)), Route::post("/posts/create", Box::new(posts_controller::create_post)), Route::post("/posts/set_visibility_level", Box::new(posts_controller::set_visibility_level)), Route::post("/posts/update_content", Box::new(posts_controller::update_content)), Route::post("/posts/delete", Box::new(posts_controller::delete)), Route::post("/posts/getAvailableTargets", Box::new(posts_controller::get_targets)), // Comments controller Route::post("/comments/create", Box::new(comments_controller::create)), Route::post("/comments/get_single", Box::new(comments_controller::get_single)), Route::post("/comments/edit", Box::new(comments_controller::edit)), Route::post("/comments/delete", Box::new(comments_controller::delete)), // Likes controller Route::post("/likes/update", Box::new(likes_controller::update)), // Surveys controller Route::post("/surveys/get_info", Box::new(surveys_controller::get_info_single)), Route::post("/surveys/send_response", Box::new(surveys_controller::send_response)), Route::post("/surveys/cancel_response", Box::new(surveys_controller::cancel_response)), Route::post("/surveys/create_new_choice", Box::new(surveys_controller::create_new_choice)), Route::post("/surveys/block_new_choices_creation", Box::new(surveys_controller::block_new_choices_creation)), // Notifications controller Route::post("/notifications/count_unread", Box::new(notifications_controller::count_unread)), Route::post("/notifications/count_all_news", Box::new(notifications_controller::count_all_news)), Route::post("/notifications/get_list_unread", Box::new(notifications_controller::get_list_unread)), Route::post("/notifications/mark_seen", Box::new(notifications_controller::mark_seen)), Route::post("/notifications/delete_all", Box::new(notifications_controller::delete_all)), // Virtual directory controller Route::post("/user/findbyfolder", Box::new(virtual_directory_controller::find_user)), Route::post("/virtualDirectory/find", Box::new(virtual_directory_controller::find)), // Web application controller Route::post("/webApp/getMemberships", Box::new(web_app_controller::get_memberships)), // Forez controller Route::post("/forez/get_groups", Box::new(forez_controller::get_list_groups)), Route::post("/forez/get_member_info", Box::new(forez_controller::get_member_info)), // === ADMIN ROUTES === // Admin accounts controller Route::limited_admin_post_without_login("/admin/accounts/auth_options", Box::new(admin_account_controller::get_auth_options), LimitPolicy::FAILURE(5)), Route::limited_admin_post_without_login("/admin/accounts/auth_with_reset_token", Box::new(admin_account_controller::auth_with_reset_token), LimitPolicy::FAILURE(5)), Route::admin_post("/admin/accounts/sign_out", Box::new(admin_account_controller::sign_out)), Route::admin_post("/admin/accounts/id", Box::new(admin_account_controller::get_admin_id)), Route::admin_post("/admin/accounts/info", Box::new(admin_account_controller::get_admin_info)), ] }