Compare commits
No commits in common. "e5748860e7b490076d08afe39cc564232418de70" and "a7004d1603613c31a74fdbe1b93281921961bd77" have entirely different histories.
e5748860e7
...
a7004d1603
6 changed files with 2 additions and 102 deletions
|
@ -22,4 +22,3 @@ openssl = "0.10" # TODO handle pubkeys with a smaller crate
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
sea-orm = { version = "0.12", features = ["macros", "sqlx-sqlite", "runtime-tokio-rustls"] }
|
sea-orm = { version = "0.12", features = ["macros", "sqlx-sqlite", "runtime-tokio-rustls"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
mdhtml = { path = "../../utils/mdhtml/" }
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
use futures::TryStreamExt;
|
|
||||||
use sea_orm::{ActiveModelTrait, ActiveValue::{Set, Unchanged}, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect, SelectColumns, TransactionTrait};
|
|
||||||
use upub::traits::{fetch::RequestError, Cloaker};
|
|
||||||
|
|
||||||
pub async fn cloak(ctx: upub::Context, post_contents: bool) -> Result<(), RequestError> {
|
|
||||||
let tx = ctx.db().begin().await?;
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut stream = upub::model::attachment::Entity::find()
|
|
||||||
.filter(upub::model::attachment::Column::Url.not_like(format!("{}%", ctx.base())))
|
|
||||||
.stream(ctx.db())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
while let Some(attachment) = stream.try_next().await? {
|
|
||||||
let (sig, url) = ctx.cloak(&attachment.url);
|
|
||||||
let mut model = attachment.into_active_model();
|
|
||||||
model.url = Set(upub::url!(ctx, "/proxy/{sig}/{url}"));
|
|
||||||
model.update(&tx).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if post_contents {
|
|
||||||
let mut stream = upub::model::object::Entity::find()
|
|
||||||
.filter(upub::model::object::Column::Content.is_not_null())
|
|
||||||
.select_only()
|
|
||||||
.select_column(upub::model::object::Column::Internal)
|
|
||||||
.select_column(upub::model::object::Column::Content)
|
|
||||||
.into_tuple::<(i64, String)>()
|
|
||||||
.stream(ctx.db())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
while let Some((internal, content)) = stream.try_next().await? {
|
|
||||||
let sanitized = mdhtml::safe_html(&content);
|
|
||||||
if sanitized != content {
|
|
||||||
let model = upub::model::object::ActiveModel {
|
|
||||||
internal: Unchanged(internal),
|
|
||||||
content: Set(Some(sanitized)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
model.update(&tx).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -22,9 +22,6 @@ pub use nuke::*;
|
||||||
mod thread;
|
mod thread;
|
||||||
pub use thread::*;
|
pub use thread::*;
|
||||||
|
|
||||||
mod cloak;
|
|
||||||
pub use cloak::*;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, clap::Subcommand)]
|
#[derive(Debug, Clone, clap::Subcommand)]
|
||||||
pub enum CliCommand {
|
pub enum CliCommand {
|
||||||
/// generate fake user, note and activity
|
/// generate fake user, note and activity
|
||||||
|
@ -112,14 +109,7 @@ pub enum CliCommand {
|
||||||
/// attempt to fix broken threads and completely gather their context
|
/// attempt to fix broken threads and completely gather their context
|
||||||
Thread {
|
Thread {
|
||||||
|
|
||||||
},
|
}
|
||||||
|
|
||||||
/// replaces all attachment urls with proxied local versions (only useful for old instances)
|
|
||||||
Cloak {
|
|
||||||
/// also replace urls inside post contents
|
|
||||||
#[arg(long, default_value_t = false)]
|
|
||||||
post_contents: bool,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(ctx: upub::Context, command: CliCommand) -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn run(ctx: upub::Context, command: CliCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -141,7 +131,5 @@ pub async fn run(ctx: upub::Context, command: CliCommand) -> Result<(), Box<dyn
|
||||||
Ok(nuke(ctx, for_real, delete_objects).await?),
|
Ok(nuke(ctx, for_real, delete_objects).await?),
|
||||||
CliCommand::Thread { } =>
|
CliCommand::Thread { } =>
|
||||||
Ok(thread(ctx).await?),
|
Ok(thread(ctx).await?),
|
||||||
CliCommand::Cloak { post_contents } =>
|
|
||||||
Ok(cloak(ctx, post_contents).await?),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,7 @@ readme = "README.md"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
async-recursion = "1.1"
|
async-recursion = "1.1"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
sha256 = "1.5" # TODO get rid of this and use directly sha2!!
|
sha256 = "1.5"
|
||||||
sha2 = "0.10"
|
|
||||||
hmac = "0.12"
|
|
||||||
openssl = "0.10" # TODO handle pubkeys with a smaller crate
|
openssl = "0.10" # TODO handle pubkeys with a smaller crate
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
use base64::{Engine, prelude::BASE64_URL_SAFE};
|
|
||||||
use hmac::Mac;
|
|
||||||
|
|
||||||
|
|
||||||
pub type Signature = hmac::Hmac<sha2::Sha256>;
|
|
||||||
|
|
||||||
pub trait Cloaker {
|
|
||||||
fn secret(&self) -> &str;
|
|
||||||
|
|
||||||
fn cloak(&self, url: &str) -> (String, String) {
|
|
||||||
let mut hmac = Signature::new_from_slice(self.secret().as_bytes())
|
|
||||||
.expect("invalid length for hmac key, cannot cloak");
|
|
||||||
hmac.update(url.as_bytes());
|
|
||||||
let sig = BASE64_URL_SAFE.encode(hmac.finalize().into_bytes());
|
|
||||||
let url = BASE64_URL_SAFE.encode(url);
|
|
||||||
(sig, url)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn uncloak(&self, signature: &str, url: &str) -> Option<String> {
|
|
||||||
let mut hmac = Signature::new_from_slice(self.secret().as_bytes())
|
|
||||||
.expect("invalid length for hmac key, cannot cloak");
|
|
||||||
|
|
||||||
let sig = BASE64_URL_SAFE.decode(signature).ok()?;
|
|
||||||
let url = std::str::from_utf8(&BASE64_URL_SAFE.decode(url).ok()?).ok()?.to_string();
|
|
||||||
|
|
||||||
hmac.update(url.as_bytes());
|
|
||||||
hmac.verify_slice(&sig).ok()?;
|
|
||||||
|
|
||||||
Some(url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Cloaker for crate::Context {
|
|
||||||
fn secret(&self) -> &str {
|
|
||||||
&self.cfg().security.proxy_secret
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,11 +3,9 @@ pub mod fetch;
|
||||||
pub mod normalize;
|
pub mod normalize;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
pub mod cloak;
|
|
||||||
|
|
||||||
pub use admin::Administrable;
|
pub use admin::Administrable;
|
||||||
pub use address::Addresser;
|
pub use address::Addresser;
|
||||||
pub use normalize::Normalizer;
|
pub use normalize::Normalizer;
|
||||||
pub use process::Processor;
|
pub use process::Processor;
|
||||||
pub use fetch::Fetcher;
|
pub use fetch::Fetcher;
|
||||||
pub use cloak::Cloaker;
|
|
||||||
|
|
Loading…
Reference in a new issue