feat: webhook init
This commit is contained in:
parent
cf2950bf99
commit
a85dbf88b9
145
Cargo.lock
generated
145
Cargo.lock
generated
@ -667,6 +667,41 @@ dependencies = [
|
|||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.20.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.20.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn 2.0.60",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.20.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.60",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.7.9"
|
version = "0.7.9"
|
||||||
@ -685,6 +720,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -906,6 +942,16 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
|
checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.0.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flume"
|
name = "flume"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -1197,7 +1243,7 @@ dependencies = [
|
|||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
@ -1218,6 +1264,12 @@ dependencies = [
|
|||||||
"rand_distr",
|
"rand_distr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.13.2"
|
version = "0.13.2"
|
||||||
@ -1480,6 +1532,12 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -1490,6 +1548,17 @@ dependencies = [
|
|||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown 0.12.3",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.2.6"
|
version = "2.2.6"
|
||||||
@ -1609,7 +1678,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.52.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2433,7 +2502,7 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
"figment",
|
"figment",
|
||||||
"futures",
|
"futures",
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"multer",
|
"multer",
|
||||||
@ -2465,7 +2534,7 @@ checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"devise",
|
"devise",
|
||||||
"glob",
|
"glob",
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rocket_http",
|
"rocket_http",
|
||||||
@ -2485,7 +2554,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"hyper 0.14.28",
|
"hyper 0.14.28",
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"pear",
|
"pear",
|
||||||
@ -2726,7 +2795,7 @@ version = "1.0.116"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
@ -2762,6 +2831,36 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_with"
|
||||||
|
version = "3.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.0",
|
||||||
|
"chrono",
|
||||||
|
"hex",
|
||||||
|
"indexmap 1.9.3",
|
||||||
|
"indexmap 2.2.6",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"serde_with_macros",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_with_macros"
|
||||||
|
version = "3.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.60",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@ -2914,7 +3013,7 @@ dependencies = [
|
|||||||
"futures-util",
|
"futures-util",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"hex",
|
"hex",
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -3112,6 +3211,12 @@ dependencies = [
|
|||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -3381,7 +3486,7 @@ version = "0.22.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
|
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
@ -3570,6 +3675,25 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq"
|
||||||
|
version = "2.9.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.0",
|
||||||
|
"flate2",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-webpki",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"url",
|
||||||
|
"webpki-roots",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -3635,9 +3759,12 @@ dependencies = [
|
|||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rocket",
|
"rocket",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_with",
|
||||||
"sha2",
|
"sha2",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"ureq",
|
||||||
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4073,6 +4200,6 @@ dependencies = [
|
|||||||
"crc32fast",
|
"crc32fast",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -26,3 +26,6 @@ blurhash = "0.2.1"
|
|||||||
candle-core = { git = "https://github.com/huggingface/candle.git", version = "0.5.1" }
|
candle-core = { git = "https://github.com/huggingface/candle.git", version = "0.5.1" }
|
||||||
candle-nn = { git = "https://github.com/huggingface/candle.git", version = "0.5.1" }
|
candle-nn = { git = "https://github.com/huggingface/candle.git", version = "0.5.1" }
|
||||||
candle-transformers = { git = "https://github.com/huggingface/candle.git", version = "0.5.1" }
|
candle-transformers = { git = "https://github.com/huggingface/candle.git", version = "0.5.1" }
|
||||||
|
ureq = { version = "2.9.7", features = ["json"] }
|
||||||
|
url = "2.5.0"
|
||||||
|
serde_with = { version = "3.8.1", features = ["hex"] }
|
||||||
|
@ -16,5 +16,8 @@ public_url = "http://localhost:8000"
|
|||||||
# Whitelisted pubkeys, leave out to disable
|
# Whitelisted pubkeys, leave out to disable
|
||||||
# whitelist = ["63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed"]
|
# whitelist = ["63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed"]
|
||||||
|
|
||||||
# Path for ViT image model (https://huggingface.co/google/vit-base-patch16-224)
|
# Path for ViT(224) image model (https://huggingface.co/google/vit-base-patch16-224)
|
||||||
# vit_model_path = "model.safetennsors"
|
# vit_model_path = "model.safetennsors"
|
||||||
|
|
||||||
|
# Webhook api endpoint
|
||||||
|
webhook_url = "https://api.snort.social/api/v1/media/webhook"
|
@ -2,11 +2,12 @@ use std::env::temp_dir;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde_with::serde_as;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeekExt};
|
use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeekExt};
|
||||||
@ -15,9 +16,11 @@ use crate::processing::{compress_file, FileProcessorResult};
|
|||||||
use crate::processing::labeling::label_frame;
|
use crate::processing::labeling::label_frame;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[serde_as]
|
||||||
|
#[derive(Clone, Default, Serialize)]
|
||||||
pub struct FileSystemResult {
|
pub struct FileSystemResult {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
|
#[serde_as(as = "serde_with::hex::Hex")]
|
||||||
pub sha256: Vec<u8>,
|
pub sha256: Vec<u8>,
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
pub mime_type: String,
|
pub mime_type: String,
|
||||||
@ -51,8 +54,11 @@ impl FileStore {
|
|||||||
let result = self.store_compress_file(stream, mime_type, compress).await?;
|
let result = self.store_compress_file(stream, mime_type, compress).await?;
|
||||||
let dst_path = self.map_path(&result.sha256);
|
let dst_path = self.map_path(&result.sha256);
|
||||||
if dst_path.exists() {
|
if dst_path.exists() {
|
||||||
fs::remove_file(&result.path)?;
|
fs::remove_file(result.path)?;
|
||||||
return Err(Error::msg("File already exists"));
|
return Ok(FileSystemResult {
|
||||||
|
path: dst_path,
|
||||||
|
..result
|
||||||
|
});
|
||||||
}
|
}
|
||||||
fs::create_dir_all(dst_path.parent().unwrap())?;
|
fs::create_dir_all(dst_path.parent().unwrap())?;
|
||||||
if let Err(e) = fs::copy(&result.path, &dst_path) {
|
if let Err(e) = fs::copy(&result.path, &dst_path) {
|
||||||
|
@ -13,6 +13,7 @@ use crate::db::Database;
|
|||||||
use crate::filesystem::FileStore;
|
use crate::filesystem::FileStore;
|
||||||
use crate::routes::{get_blob, head_blob, root};
|
use crate::routes::{get_blob, head_blob, root};
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
use crate::webhook::Webhook;
|
||||||
|
|
||||||
mod auth;
|
mod auth;
|
||||||
mod blob;
|
mod blob;
|
||||||
@ -22,6 +23,7 @@ mod filesystem;
|
|||||||
mod routes;
|
mod routes;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod processing;
|
mod processing;
|
||||||
|
mod webhook;
|
||||||
|
|
||||||
#[rocket::main]
|
#[rocket::main]
|
||||||
async fn main() -> Result<(), Error> {
|
async fn main() -> Result<(), Error> {
|
||||||
@ -58,6 +60,7 @@ async fn main() -> Result<(), Error> {
|
|||||||
.manage(FileStore::new(settings.clone()))
|
.manage(FileStore::new(settings.clone()))
|
||||||
.manage(settings.clone())
|
.manage(settings.clone())
|
||||||
.manage(db.clone())
|
.manage(db.clone())
|
||||||
|
.manage(settings.webhook_url.as_ref().map(|w| Webhook::new(w.clone())))
|
||||||
.attach(CORS)
|
.attach(CORS)
|
||||||
.attach(Shield::new()) // disable
|
.attach(Shield::new()) // disable
|
||||||
.mount("/", routes::blossom_routes())
|
.mount("/", routes::blossom_routes())
|
||||||
|
@ -17,6 +17,7 @@ use crate::db::{Database, FileUpload};
|
|||||||
use crate::filesystem::FileStore;
|
use crate::filesystem::FileStore;
|
||||||
use crate::routes::delete_file;
|
use crate::routes::delete_file;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
use crate::webhook::Webhook;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct BlossomError {
|
struct BlossomError {
|
||||||
@ -82,6 +83,7 @@ async fn upload(
|
|||||||
fs: &State<FileStore>,
|
fs: &State<FileStore>,
|
||||||
db: &State<Database>,
|
db: &State<Database>,
|
||||||
settings: &State<Settings>,
|
settings: &State<Settings>,
|
||||||
|
webhook: &State<Option<Webhook>>,
|
||||||
data: Data<'_>,
|
data: Data<'_>,
|
||||||
) -> BlossomResponse {
|
) -> BlossomResponse {
|
||||||
if !check_method(&auth.event, "upload") {
|
if !check_method(&auth.event, "upload") {
|
||||||
@ -122,6 +124,18 @@ async fn upload(
|
|||||||
{
|
{
|
||||||
Ok(blob) => {
|
Ok(blob) => {
|
||||||
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
||||||
|
if let Some(wh) = webhook.as_ref() {
|
||||||
|
match wh.store_file(&pubkey_vec, blob.clone()) {
|
||||||
|
Ok(store) => if !store {
|
||||||
|
let _ = fs::remove_file(blob.path);
|
||||||
|
return BlossomResponse::error("Upload rejected");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
let _ = fs::remove_file(blob.path);
|
||||||
|
return BlossomResponse::error(format!("Internal error, failed to call webhook: {}", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let user_id = match db.upsert_user(&pubkey_vec).await {
|
let user_id = match db.upsert_user(&pubkey_vec).await {
|
||||||
Ok(u) => u,
|
Ok(u) => u,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -14,6 +14,7 @@ use crate::db::{Database, FileUpload};
|
|||||||
use crate::filesystem::FileStore;
|
use crate::filesystem::FileStore;
|
||||||
use crate::routes::delete_file;
|
use crate::routes::delete_file;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
use crate::webhook::Webhook;
|
||||||
|
|
||||||
#[derive(Serialize, Default)]
|
#[derive(Serialize, Default)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
@ -152,6 +153,7 @@ async fn upload(
|
|||||||
fs: &State<FileStore>,
|
fs: &State<FileStore>,
|
||||||
db: &State<Database>,
|
db: &State<Database>,
|
||||||
settings: &State<Settings>,
|
settings: &State<Settings>,
|
||||||
|
webhook: &State<Option<Webhook>>,
|
||||||
form: Form<Nip96Form<'_>>,
|
form: Form<Nip96Form<'_>>,
|
||||||
) -> Nip96Response {
|
) -> Nip96Response {
|
||||||
if let Some(size) = auth.content_length {
|
if let Some(size) = auth.content_length {
|
||||||
@ -178,6 +180,18 @@ async fn upload(
|
|||||||
{
|
{
|
||||||
Ok(blob) => {
|
Ok(blob) => {
|
||||||
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
||||||
|
if let Some(wh) = webhook.as_ref() {
|
||||||
|
match wh.store_file(&pubkey_vec, blob.clone()) {
|
||||||
|
Ok(store) => if !store {
|
||||||
|
let _ = fs::remove_file(blob.path);
|
||||||
|
return Nip96Response::error("Upload rejected");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
let _ = fs::remove_file(blob.path);
|
||||||
|
return Nip96Response::error(&format!("Internal error, failed to call webhook: {}", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let user_id = match db.upsert_user(&pubkey_vec).await {
|
let user_id = match db.upsert_user(&pubkey_vec).await {
|
||||||
Ok(u) => u,
|
Ok(u) => u,
|
||||||
Err(e) => return Nip96Response::error(&format!("Could not save user: {}", e)),
|
Err(e) => return Nip96Response::error(&format!("Could not save user: {}", e)),
|
||||||
|
@ -22,5 +22,8 @@ pub struct Settings {
|
|||||||
pub whitelist: Option<Vec<String>>,
|
pub whitelist: Option<Vec<String>>,
|
||||||
|
|
||||||
/// Path for ViT image model
|
/// Path for ViT image model
|
||||||
pub vit_model_path: Option<PathBuf>
|
pub vit_model_path: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Webhook api endpoint
|
||||||
|
pub webhook_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
41
src/webhook.rs
Normal file
41
src/webhook.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use anyhow::Error;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::filesystem::FileSystemResult;
|
||||||
|
|
||||||
|
pub(crate) struct Webhook {
|
||||||
|
url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct WebhookRequest<T> {
|
||||||
|
pub action: String,
|
||||||
|
pub subject: Option<String>,
|
||||||
|
pub payload: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Webhook {
|
||||||
|
pub fn new(url: String) -> Self {
|
||||||
|
Self {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ask webhook api if this file can be accepted
|
||||||
|
pub fn store_file(&self, pubkey: &Vec<u8>, fs: FileSystemResult) -> Result<bool, Error> {
|
||||||
|
let body: WebhookRequest<FileSystemResult> = WebhookRequest {
|
||||||
|
action: "store_file".to_string(),
|
||||||
|
subject: Some(hex::encode(pubkey)),
|
||||||
|
payload: fs,
|
||||||
|
};
|
||||||
|
let req = ureq::post(&self.url)
|
||||||
|
.set("accept", "application/json")
|
||||||
|
.send_json(body)?;
|
||||||
|
|
||||||
|
if req.status() == 200 {
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user