From 5fab1105135d7e43a3f23255da76020ea4386db8 Mon Sep 17 00:00:00 2001 From: blek Date: Wed, 13 Dec 2023 20:49:33 +1000 Subject: [PATCH] properly implement delete method according to config --- filed/docs/file_api.swagger.yml | 5 +- filed/src/web/api/files.rs | 4 +- filed/src/web/api/files/delete.rs | 78 +++++++++++++++++++++++++++--- filed/src/web/api/files/get_all.rs | 2 +- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/filed/docs/file_api.swagger.yml b/filed/docs/file_api.swagger.yml index 23758cb..7539d45 100644 --- a/filed/docs/file_api.swagger.yml +++ b/filed/docs/file_api.swagger.yml @@ -74,7 +74,7 @@ paths: example: {} 401: description: |- - This error code is returned if one of the two conditions are met: + This error code is returned if one of these conditions are met: 1. The instance does not allow deleting files via API. 2. The file has been uploaded from another IP, which is not this one, and the API was not authorized via an API key. @@ -90,6 +90,9 @@ paths: fid: type: string example: ID or name of the file. It is the NAME in file.blek.codes/uploads/NAME + api_key: + type: string + example: '123' /api/files/upload: post: summary: Upload a file diff --git a/filed/src/web/api/files.rs b/filed/src/web/api/files.rs index 631e861..70d7522 100644 --- a/filed/src/web/api/files.rs +++ b/filed/src/web/api/files.rs @@ -49,10 +49,10 @@ fn check_api_pass(state: &SharedState, key: String) -> Result<(), WithStatus WithStatus { +fn function_disabled_err(status: StatusCode) -> WithStatus { warp::reply::with_status( json(&ErrorMessage::new(Error::APIFunctionDisabled)), - StatusCode::SERVICE_UNAVAILABLE + status ) } diff --git a/filed/src/web/api/files/delete.rs b/filed/src/web/api/files/delete.rs index b585d4e..b10b67e 100644 --- a/filed/src/web/api/files/delete.rs +++ b/filed/src/web/api/files/delete.rs @@ -1,26 +1,56 @@ -use std::collections::HashMap; +use std::{collections::HashMap, net::IpAddr}; -use warp::{reply::{Reply, json}, reject::Rejection, Filter, http::StatusCode}; +use warp::{reply::{Reply, json, with_status}, reject::Rejection, Filter, http::StatusCode}; use serde::{Serialize, Deserialize}; +use warp_real_ip::real_ip; -use crate::web::{state::SharedState, rejection::HttpReject, api::types::{ErrorMessage, Error}}; +use crate::{web::{state::SharedState, rejection::HttpReject, api::types::{ErrorMessage, Error}}, files::File}; use super::{function_disabled_err, check_api_enabled}; #[derive(Serialize, Deserialize, Clone, Debug)] pub struct DeleteFunctionPayload { - pub fid: String + pub fid: String, + pub api_key: Option } -pub async fn delete(state: SharedState, body: DeleteFunctionPayload) -> Result, Rejection> { +pub async fn delete(state: SharedState, body: DeleteFunctionPayload, ip: Option) -> Result, Rejection> { if let Err(res) = check_api_enabled(&state) { return Ok(Box::new(res)); } if (!state.config.api.delete) || (!state.config.api.enabled) { - return Ok(Box::new(function_disabled_err())) + return Ok(Box::new(function_disabled_err(StatusCode::UNAUTHORIZED))) } + let mut sudo_authorized = false; + let mut blocked = false; + + if let Some(keys) = state.config.api.apikeys.clone() { + if let Some(key) = body.api_key { + + if keys.contains(&key) { + sudo_authorized = true; + blocked = false; + } else { + sudo_authorized = false; + blocked = true; + } + + } else { + sudo_authorized = false; + blocked = true + } + } + + if ! sudo_authorized { + if ip.is_none() { // need the ip if sudo is not authorized + blocked = true // to check if the file is the own file + } + } + + let ip = ip.unwrap(); + let id = body.fid; let mut file = state.file_mgr.find_by_hash(id.clone()) .map_err(|x| HttpReject::StringError(x.to_string()))?; @@ -30,7 +60,7 @@ pub async fn delete(state: SharedState, body: DeleteFunctionPayload) -> Result Result::new()))) } pub fn delete_f(state: SharedState) -> impl Filter + Clone { + + let proxy_ip = state.env.proxy_addr; + warp::path!("api" / "files" / "delete") .map(move || state.clone()) .and(warp::body::json()) + .and(real_ip(vec![proxy_ip])) .and_then(delete) } \ No newline at end of file diff --git a/filed/src/web/api/files/get_all.rs b/filed/src/web/api/files/get_all.rs index 8ec34a7..9502139 100644 --- a/filed/src/web/api/files/get_all.rs +++ b/filed/src/web/api/files/get_all.rs @@ -13,7 +13,7 @@ pub async fn get_all(state: SharedState, ip: Option) -> Result