@@ -162,6 +162,10 @@ impl DBConnection {
 | 
			
		||||
 | 
			
		||||
    pub fn save_node(&mut self, span: &Span, node: &super::Inode) { DB_MANAGER.save_node(span, &mut self.db, node); }
 | 
			
		||||
 | 
			
		||||
    pub fn move_node(&mut self, span: &Span, node: &mut super::Inode, target: i32) {
 | 
			
		||||
        DB_MANAGER.move_node(span, &mut self.db, node, target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn delete_node(&mut self, span: &Span, node: &super::Inode) {
 | 
			
		||||
        DB_MANAGER.delete_node(span, &mut self.db, node);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -124,6 +124,12 @@ impl DBManager {
 | 
			
		||||
        diesel::update(node).set(node.clone()).execute(db).expect("Failed to save node");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn move_node(&self, span: &Span, db: &mut super::RawDBConnection, node: &mut Inode, target: i32) {
 | 
			
		||||
        self.children_cache.remove(&node.parent_id.unwrap_or(0));
 | 
			
		||||
        node.parent_id = Some(target);
 | 
			
		||||
        self.save_node(span, db, node);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn delete_node(&self, span: &Span, db: &mut super::RawDBConnection, node: &Inode) {
 | 
			
		||||
        let inner_span = metrics::span("delete_node", span);
 | 
			
		||||
        let owner = node.owner_id.to_string();
 | 
			
		||||
 
 | 
			
		||||
@@ -186,6 +186,12 @@ pub mod requests {
 | 
			
		||||
        pub name: String
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug, Deserialize, Serialize, Clone)]
 | 
			
		||||
    pub struct MoveNode {
 | 
			
		||||
        pub nodes: Vec<i32>,
 | 
			
		||||
        pub target: i32
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug, Deserialize, Serialize, Clone)]
 | 
			
		||||
    pub struct CreateZip {
 | 
			
		||||
        pub nodes: Vec<i32>
 | 
			
		||||
 
 | 
			
		||||
@@ -77,16 +77,18 @@ fn handle_request(mut req: Request, db: db::DBPool) {
 | 
			
		||||
                    AppError::NotFound => 404,
 | 
			
		||||
                    AppError::InternalError(_) => 500
 | 
			
		||||
                };
 | 
			
		||||
                let msg = match v {
 | 
			
		||||
                    AppError::BadRequest(v) => v.to_string(),
 | 
			
		||||
                    AppError::Unauthorized(v) => v.to_string(),
 | 
			
		||||
                    AppError::Forbidden(v) => v.to_string(),
 | 
			
		||||
                    AppError::NotFound => "Not found".to_owned(),
 | 
			
		||||
                    AppError::InternalError(v) => v.to_string()
 | 
			
		||||
                };
 | 
			
		||||
                span.set_tag(|| Tag::new("http.error_msg", msg.clone()));
 | 
			
		||||
                Response::from_data(
 | 
			
		||||
                    serde_json::to_vec(&dto::responses::Error {
 | 
			
		||||
                        statusCode: code,
 | 
			
		||||
                        message: match v {
 | 
			
		||||
                            AppError::BadRequest(v) => v.to_string(),
 | 
			
		||||
                            AppError::Unauthorized(v) => v.to_string(),
 | 
			
		||||
                            AppError::Forbidden(v) => v.to_string(),
 | 
			
		||||
                            AppError::NotFound => "Not found".to_owned(),
 | 
			
		||||
                            AppError::InternalError(v) => v.to_string()
 | 
			
		||||
                        }
 | 
			
		||||
                        message: msg
 | 
			
		||||
                    })
 | 
			
		||||
                    .unwrap()
 | 
			
		||||
                )
 | 
			
		||||
@@ -165,6 +167,7 @@ fn handle_api_request(span: &mut Span, req: &mut Request, pool: db::DBPool) -> R
 | 
			
		||||
                ("/api/fs/create_zip",          Method::Post, None)         => parse_body(span, req).and_then(|v| routes::fs::routes::create_zip(span, req, db, info, v, &pool)),
 | 
			
		||||
                ("/api/fs/download_preview",    Method::Get, Some(v))   => routes::fs::routes::download_preview(span, req, db, info, v),
 | 
			
		||||
                ("/api/fs/get_type",            Method::Get, Some(v))   => routes::fs::routes::get_type(span, req, db, info, v),
 | 
			
		||||
                ("/api/fs/move",                Method::Post, None)         => parse_body(span, req).and_then(|v| routes::fs::routes::move_node(span, req, db, info, v)),
 | 
			
		||||
                _ => AppError::NotFound.err()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -549,3 +549,43 @@ pub fn get_type(
 | 
			
		||||
        _type: mime_guess::from_path(std::path::Path::new(&node.name)).first_or_octet_stream().to_string()
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn move_node(
 | 
			
		||||
    span: &Span,
 | 
			
		||||
    _: &mut Request,
 | 
			
		||||
    db: &mut DBConnection,
 | 
			
		||||
    info: UserInfo,
 | 
			
		||||
    data: dto::requests::MoveNode
 | 
			
		||||
) -> Result<ResponseBox, AppError> {
 | 
			
		||||
    let guard_lock = DBConnection::get_lock(info.0.id);
 | 
			
		||||
    let _guard = guard_lock.write(span);
 | 
			
		||||
 | 
			
		||||
    let target =
 | 
			
		||||
        super::get_node_and_validate(span, &info.0, data.target, db).ok_or(AppError::BadRequest("Invalid target"))?;
 | 
			
		||||
    if target.is_file {
 | 
			
		||||
        return AppError::BadRequest("Invalid target").err();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut nodes = data
 | 
			
		||||
        .nodes
 | 
			
		||||
        .iter()
 | 
			
		||||
        .map(|v| super::get_node_and_validate(span, &info.0, *v, db))
 | 
			
		||||
        .into_iter()
 | 
			
		||||
        .collect::<Option<Vec<db::Inode>>>()
 | 
			
		||||
        .ok_or(AppError::BadRequest("Invalid node"))?;
 | 
			
		||||
 | 
			
		||||
    for parent in super::get_node_path(span, target.clone(), db) {
 | 
			
		||||
        if nodes.contains(&parent) {
 | 
			
		||||
            return AppError::BadRequest("Can't move node into one of it's subfolders").err();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    for child in db.get_children(span, target.id) {
 | 
			
		||||
        if nodes.iter().any(|n| n.name == child.name) {
 | 
			
		||||
            return AppError::BadRequest("Can't overwrite existing file").err();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nodes.iter_mut().for_each(|n| db.move_node(span, n, target.id));
 | 
			
		||||
 | 
			
		||||
    get_reply(&dto::responses::Success { statusCode: 200 })
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user