mirror of
				https://gitlab.com/comunic/comunicapiv3
				synced 2025-11-04 09:34:04 +00:00 
			
		
		
		
	Add support for admin routes
This commit is contained in:
		
							
								
								
									
										12
									
								
								src/controllers/admin/admin_account_controller.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/controllers/admin/admin_account_controller.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
//! # Admin account controller
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
use crate::data::http_request_handler::HttpRequestHandler;
 | 
			
		||||
use crate::routes::RequestResult;
 | 
			
		||||
use crate::data::base_request_handler::BaseRequestHandler;
 | 
			
		||||
 | 
			
		||||
/// Get admin auth options
 | 
			
		||||
pub fn get_auth_options(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    r.ok()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								src/controllers/admin/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/controllers/admin/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
//! # Admin controllers
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
pub mod admin_account_controller;
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
pub mod admin;
 | 
			
		||||
 | 
			
		||||
pub mod server_controller;
 | 
			
		||||
pub mod user_ws_controller;
 | 
			
		||||
pub mod rtc_relay_controller;
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,7 @@ pub struct Config {
 | 
			
		||||
    pub independent_push_service: Option<IndependentPushService>,
 | 
			
		||||
    pub database: DatabaseConfig,
 | 
			
		||||
    pub rtc_relay: Option<RtcRelayConfig>,
 | 
			
		||||
    pub admin_url: String,
 | 
			
		||||
    pub forez_groups: Vec<GroupID>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -152,6 +153,8 @@ impl Config {
 | 
			
		||||
 | 
			
		||||
            rtc_relay: rtc_config,
 | 
			
		||||
 | 
			
		||||
            admin_url: Self::yaml_str(parsed, "admin-url"),
 | 
			
		||||
 | 
			
		||||
            forez_groups: parsed["forez_groups"]
 | 
			
		||||
                .as_vec()
 | 
			
		||||
                .unwrap_or(&vec![])
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,17 @@ impl HttpRequestHandler {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check admin origin
 | 
			
		||||
    pub fn check_admin_origin(&mut self) -> Res {
 | 
			
		||||
        if let Some(header) = self.request.headers().get("Origin") {
 | 
			
		||||
            if header.to_str()?.eq(&conf().admin_url) {
 | 
			
		||||
                return Ok(());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.bad_request("Invalid origin for admin requests!".to_string())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl BaseRequestHandler for HttpRequestHandler {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
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};
 | 
			
		||||
 | 
			
		||||
@@ -34,6 +35,15 @@ pub enum LimitPolicy {
 | 
			
		||||
    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)
 | 
			
		||||
@@ -54,6 +64,9 @@ pub type RequestResult = Result<(), Box<dyn Error>>;
 | 
			
		||||
pub type RequestProcess = Box<dyn Fn(&mut HttpRequestHandler) -> RequestResult>;
 | 
			
		||||
 | 
			
		||||
pub struct Route {
 | 
			
		||||
    /// Route scope
 | 
			
		||||
    pub scope: RouteScope,
 | 
			
		||||
 | 
			
		||||
    /// The Verb used for the request
 | 
			
		||||
    pub method: Method,
 | 
			
		||||
 | 
			
		||||
@@ -73,6 +86,7 @@ pub struct Route {
 | 
			
		||||
impl Route {
 | 
			
		||||
    pub fn get_without_login(uri: &'static str, func: RequestProcess) -> Route {
 | 
			
		||||
        Route {
 | 
			
		||||
            scope: RouteScope::USER,
 | 
			
		||||
            method: GET,
 | 
			
		||||
            need_login: false,
 | 
			
		||||
            uri,
 | 
			
		||||
@@ -83,6 +97,7 @@ impl Route {
 | 
			
		||||
 | 
			
		||||
    pub fn post_without_login(uri: &'static str, func: RequestProcess) -> Route {
 | 
			
		||||
        Route {
 | 
			
		||||
            scope: RouteScope::USER,
 | 
			
		||||
            method: POST,
 | 
			
		||||
            need_login: false,
 | 
			
		||||
            uri,
 | 
			
		||||
@@ -93,6 +108,7 @@ impl Route {
 | 
			
		||||
 | 
			
		||||
    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,
 | 
			
		||||
@@ -103,6 +119,7 @@ impl Route {
 | 
			
		||||
 | 
			
		||||
    pub fn post(uri: &'static str, func: RequestProcess) -> Route {
 | 
			
		||||
        Route {
 | 
			
		||||
            scope: RouteScope::USER,
 | 
			
		||||
            method: POST,
 | 
			
		||||
            need_login: true,
 | 
			
		||||
            uri,
 | 
			
		||||
@@ -113,6 +130,7 @@ impl Route {
 | 
			
		||||
 | 
			
		||||
    pub fn limited_post(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route {
 | 
			
		||||
        Route {
 | 
			
		||||
            scope: RouteScope::USER,
 | 
			
		||||
            method: POST,
 | 
			
		||||
            need_login: true,
 | 
			
		||||
            uri,
 | 
			
		||||
@@ -120,6 +138,17 @@ impl Route {
 | 
			
		||||
            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,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the list of routes available
 | 
			
		||||
@@ -301,5 +330,12 @@ pub fn get_routes() -> Vec<Route> {
 | 
			
		||||
        // 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)),
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -18,7 +18,7 @@ use crate::data::base_request_handler::{BaseRequestHandler, PostFile, RequestVal
 | 
			
		||||
use crate::data::config::Config;
 | 
			
		||||
use crate::data::http_request_handler::HttpRequestHandler;
 | 
			
		||||
use crate::helpers::{api_helper, requests_limit_helper};
 | 
			
		||||
use crate::routes::{get_routes, RequestResult, Route};
 | 
			
		||||
use crate::routes::{get_routes, RequestResult, Route, RouteScope};
 | 
			
		||||
use crate::routes::Method::{GET, POST};
 | 
			
		||||
use crate::utils::user_data_utils::user_data_path;
 | 
			
		||||
 | 
			
		||||
@@ -209,14 +209,33 @@ fn process_simple_route(route: &Route, req: &mut HttpRequestHandler) -> RequestR
 | 
			
		||||
        req.too_many_requests("Too many request. Please try again later.")?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Validate client token
 | 
			
		||||
    req.check_client_token()?;
 | 
			
		||||
    // Check if the user is allowed to access the route
 | 
			
		||||
    match route.scope {
 | 
			
		||||
 | 
			
		||||
    // Check user token, if required
 | 
			
		||||
    if route.need_login || req.has_post_parameter("userToken1") {
 | 
			
		||||
        req.check_user_token()?;
 | 
			
		||||
        // "Normal" user route
 | 
			
		||||
        RouteScope::USER => {
 | 
			
		||||
            // Validate client token
 | 
			
		||||
            req.check_client_token()?;
 | 
			
		||||
 | 
			
		||||
            // Check user token, if required
 | 
			
		||||
            if route.need_login || req.has_post_parameter("token") {
 | 
			
		||||
                req.check_user_token()?;
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        // "Admin" user scope
 | 
			
		||||
        RouteScope::ADMIN => {
 | 
			
		||||
            req.check_admin_origin()?;
 | 
			
		||||
 | 
			
		||||
            if route.need_login {
 | 
			
		||||
                // TODO : implement
 | 
			
		||||
                unimplemented!();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    let res: RequestResult = (route.func)(req);
 | 
			
		||||
 | 
			
		||||
    requests_limit_helper::trigger_after(res.is_ok(), req, route)?;
 | 
			
		||||
@@ -250,7 +269,7 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse {
 | 
			
		||||
 | 
			
		||||
    // Check if a route was found
 | 
			
		||||
    if let None = route {
 | 
			
		||||
        return HttpResponse::NotFound().json(HttpError::not_found("Method not found!"));
 | 
			
		||||
        return HttpResponse::NotFound().json(HttpError::not_found("Route not found!"));
 | 
			
		||||
    }
 | 
			
		||||
    let route = route.unwrap();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user