Whitelist / better duplicate file response
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
kieran 2024-05-14 10:58:21 +01:00
parent 1a27f19e50
commit f16e7acadb
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 61 additions and 10 deletions

View File

@ -11,4 +11,7 @@ storage_dir = "./data"
max_upload_bytes = 104857600
# Public facing url
public_url = "http://localhost:8000"
public_url = "http://localhost:8000"
# Whitelisted pubkeys, leave out to disable
# whitelist = ["63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed"]

View File

@ -26,14 +26,14 @@ pub struct FileSystemResult {
}
pub struct FileStore {
path: String,
settings: Settings,
processor: Arc<Mutex<MediaProcessor>>,
}
impl FileStore {
pub fn new(settings: Settings) -> Self {
Self {
path: settings.storage_dir,
settings,
processor: Arc::new(Mutex::new(MediaProcessor::new())),
}
}
@ -50,6 +50,10 @@ impl FileStore {
{
let result = self.store_compress_file(stream, mime_type, compress).await?;
let dst_path = self.map_path(&result.sha256);
if dst_path.exists() {
fs::remove_file(&result.path)?;
return Err(Error::msg("File already exists"));
}
fs::create_dir_all(dst_path.parent().unwrap())?;
if let Err(e) = fs::copy(&result.path, &dst_path) {
fs::remove_file(&result.path)?;
@ -71,6 +75,7 @@ impl FileStore {
let tmp_path = FileStore::map_temp(random_id);
let mut file = File::options()
.create(true)
.truncate(false)
.write(true)
.read(true)
.open(tmp_path.clone())
@ -83,7 +88,7 @@ impl FileStore {
let start = SystemTime::now();
let proc_result = {
let mut p_lock = self.processor.lock().expect("asd");
p_lock.process_file(tmp_path.clone(), &mime_type)?
p_lock.process_file(tmp_path.clone(), mime_type)?
};
if let FileProcessorResult::NewFile(new_temp) = proc_result {
let old_size = tmp_path.metadata()?.len();
@ -99,6 +104,7 @@ impl FileStore {
fs::remove_file(tmp_path)?;
file = File::options()
.create(true)
.truncate(false)
.write(true)
.read(true)
.open(new_temp.result.clone())
@ -150,9 +156,9 @@ impl FileStore {
fn map_path(&self, id: &Vec<u8>) -> PathBuf {
let id = hex::encode(id);
Path::new(&self.path)
.join(id[0..2].to_string())
.join(id[2..4].to_string())
Path::new(&self.settings.storage_dir)
.join(&id[0..2])
.join(&id[2..4])
.join(id)
}
}

View File

@ -1,3 +1,5 @@
use std::fs;
use chrono::Utc;
use log::error;
use nostr::prelude::hex;
@ -105,6 +107,12 @@ async fn upload(
.content_type
.unwrap_or("application/octet-stream".to_string());
// check whitelist
if let Some(wl) = &settings.whitelist {
if !wl.contains(&auth.event.pubkey.to_hex()) {
return BlossomResponse::error("Not on whitelist");
}
}
match fs
.put(data.open(ByteUnit::from(settings.max_upload_bytes)), &mime_type, false)
.await
@ -126,7 +134,15 @@ async fn upload(
created: Utc::now(),
};
if let Err(e) = db.add_file(&f).await {
error!("{:?}", e);
error!("{}", e.to_string());
let _ = fs::remove_file(blob.path);
if let Some(dbe) = e.as_database_error() {
if let Some(c) = dbe.code() {
if c == "23000" {
return BlossomResponse::error("File already exists");
}
}
}
BlossomResponse::error(format!("Error saving file (db): {}", e))
} else {
BlossomResponse::BlobDescriptor(Json(BlobDescriptor::from_upload(
@ -136,7 +152,7 @@ async fn upload(
}
}
Err(e) => {
error!("{:?}", e);
error!("{}", e.to_string());
BlossomResponse::error(format!("Error saving file (disk): {}", e))
}
}

View File

@ -1,6 +1,10 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs;
use chrono::Utc;
use libc::remove;
use log::error;
use rocket::{FromForm, Responder, Route, routes, State};
use rocket::form::Form;
use rocket::fs::TempFile;
@ -158,6 +162,13 @@ async fn upload(
};
let mime_type = form.media_type
.unwrap_or("application/octet-stream");
// check whitelist
if let Some(wl) = &settings.whitelist {
if !wl.contains(&auth.event.pubkey.to_hex()) {
return Nip96Response::error("Not on whitelist");
}
}
match fs
.put(file, mime_type, true)
.await
@ -180,6 +191,15 @@ async fn upload(
created: Utc::now(),
};
if let Err(e) = db.add_file(&file_upload).await {
error!("{}", e.to_string());
let _ = fs::remove_file(blob.path);
if let Some(dbe) = e.as_database_error() {
if let Some(c) = dbe.code() {
if c == "23000" {
return Nip96Response::error("File already exists");
}
}
}
return Nip96Response::error(&format!("Could not save file (db): {}", e));
}
@ -207,7 +227,10 @@ async fn upload(
..Default::default()
}))
}
Err(e) => return Nip96Response::error(&format!("Could not save file: {}", e)),
Err(e) => {
error!("{}", e.to_string());
Nip96Response::error(&format!("Could not save file: {}", e))
}
}
}

View File

@ -16,4 +16,7 @@ pub struct Settings {
/// Public facing url
pub public_url: String,
/// Whitelisted pubkeys
pub whitelist: Option<Vec<String>>
}