-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: block instances and actors (#67)
* refactor(migration): add blocked_{instance,actor} * chore: update flake lock * refactor(schema)!: regenerate * fix(migration/activity): fix type * fix(schema/activity): fix type * fix(apub): update activity type * refactor(migration)!: simplify table * refactor(schema)!: regenerate * feat(api_admin): block url * refactor(api_admin/block_url): check query * feat(apub): verify blocked * fix(api_admin/block_url): fix docs * fix(api_admin/auth): split query * feat(api_admin): unblock url * fix(api_admin/block_url): update status code * fix(apub/verify_blocked): use iter
- Loading branch information
Showing
31 changed files
with
298 additions
and
37 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
use serde::{Deserialize, Serialize}; | ||
use url::Url; | ||
use utoipa::{IntoParams, ToSchema}; | ||
|
||
#[derive(Deserialize, IntoParams)] | ||
pub struct BlockUrlQuery { | ||
pub url: Url, | ||
} | ||
|
||
#[derive(Serialize, ToSchema)] | ||
pub struct BlockUrlResult { | ||
pub url: Url, | ||
pub message: String, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
mod block_url_or_acct; | ||
mod create_remove_account; | ||
|
||
pub use block_url_or_acct::{BlockUrlQuery, BlockUrlResult}; | ||
pub use create_remove_account::{CreateRemoveAccount, CreateRemoveAccountResult}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
use activitypub_federation::config::Data; | ||
use axum::{debug_handler, extract::Query, http::StatusCode, Json}; | ||
use hatsu_db_schema::{blocked_url, prelude::BlockedUrl}; | ||
use hatsu_utils::{AppData, AppError}; | ||
use sea_orm::{ActiveModelTrait, EntityTrait, Set}; | ||
|
||
use crate::{ | ||
entities::{BlockUrlQuery, BlockUrlResult}, | ||
TAG, | ||
}; | ||
|
||
/// Block URL | ||
#[utoipa::path( | ||
post, | ||
tag = TAG, | ||
path = "/api/v0/admin/block-url", | ||
params(BlockUrlQuery), | ||
responses( | ||
(status = OK, description = "block successfully", body = BlockUrlResult), | ||
(status = BAD_REQUEST, description = "error", body = AppError) | ||
), | ||
security(("api_key" = ["token"])) | ||
)] | ||
#[debug_handler] | ||
pub async fn block_url( | ||
data: Data<AppData>, | ||
query: Query<BlockUrlQuery>, | ||
) -> Result<(StatusCode, Json<BlockUrlResult>), AppError> { | ||
match &query.url { | ||
url if url.query().is_some() => Err(AppError::new( | ||
format!( | ||
"wrong url: {} (can't contain search params)", | ||
url.to_string() | ||
), | ||
None, | ||
Some(StatusCode::BAD_REQUEST), | ||
)), | ||
_ => match BlockedUrl::find_by_id(&query.url.to_string()) | ||
.one(&data.conn) | ||
.await? | ||
{ | ||
Some(url) => Err(AppError::new( | ||
format!("The url already blocked: {}", url.id), | ||
None, | ||
Some(StatusCode::BAD_REQUEST), | ||
)), | ||
None => { | ||
blocked_url::ActiveModel { | ||
id: Set(query.url.to_string()), | ||
is_instance: Set(query.url.path().eq("/")), | ||
} | ||
.insert(&data.conn) | ||
.await?; | ||
|
||
Ok(( | ||
StatusCode::OK, | ||
Json(BlockUrlResult { | ||
url: query.url.clone(), | ||
message: format!( | ||
"The url was successfully blocked: {}", | ||
&query.url.to_string() | ||
), | ||
}), | ||
)) | ||
}, | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use activitypub_federation::config::Data; | ||
use axum::{debug_handler, extract::Query, http::StatusCode, Json}; | ||
use hatsu_db_schema::prelude::BlockedUrl; | ||
use hatsu_utils::{AppData, AppError}; | ||
use sea_orm::{EntityTrait, ModelTrait}; | ||
|
||
use crate::{ | ||
entities::{BlockUrlQuery, BlockUrlResult}, | ||
TAG, | ||
}; | ||
|
||
/// Unblock URL | ||
#[utoipa::path( | ||
post, | ||
tag = TAG, | ||
path = "/api/v0/admin/unblock-url", | ||
params(BlockUrlQuery), | ||
responses( | ||
(status = OK, description = "unblock successfully", body = BlockUrlResult), | ||
(status = BAD_REQUEST, description = "error", body = AppError) | ||
), | ||
security(("api_key" = ["token"])) | ||
)] | ||
#[debug_handler] | ||
pub async fn unblock_url( | ||
data: Data<AppData>, | ||
query: Query<BlockUrlQuery>, | ||
) -> Result<(StatusCode, Json<BlockUrlResult>), AppError> { | ||
match BlockedUrl::find_by_id(&query.url.to_string()) | ||
.one(&data.conn) | ||
.await? | ||
{ | ||
Some(url) => { | ||
url.delete(&data.conn).await?; | ||
|
||
Ok(( | ||
StatusCode::OK, | ||
Json(BlockUrlResult { | ||
url: query.url.clone(), | ||
message: format!( | ||
"The url was successfully unblocked: {}", | ||
&query.url.to_string() | ||
), | ||
}), | ||
)) | ||
}, | ||
None => Err(AppError::new( | ||
format!("The url doesn't exist: {}", query.url.to_string()), | ||
None, | ||
Some(StatusCode::BAD_REQUEST), | ||
)), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
mod verify_blocked; | ||
|
||
pub use verify_blocked::verify_blocked; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use activitypub_federation::config::Data; | ||
use axum::http::StatusCode; | ||
use hatsu_db_schema::prelude::BlockedUrl; | ||
use hatsu_utils::{AppData, AppError}; | ||
use sea_orm::EntityTrait; | ||
use url::Url; | ||
|
||
pub async fn verify_blocked(url: &Url, data: &Data<AppData>) -> Result<(), AppError> { | ||
let blocked_url = BlockedUrl::find().all(&data.conn).await?; | ||
|
||
if blocked_url | ||
.iter() | ||
.filter(|url| url.is_instance) | ||
.filter_map(|url| Url::parse(&url.id).ok()) | ||
.map(|url| url.origin()) | ||
.any(|instance| url.origin().eq(&instance)) | ||
{ | ||
Err(AppError::new( | ||
format!("blocked instance: {:?}", url.host_str()), | ||
None, | ||
Some(StatusCode::BAD_REQUEST), | ||
)) | ||
} else if blocked_url | ||
.iter() | ||
.filter(|url| !url.is_instance) | ||
.filter_map(|url| Url::parse(&url.id).ok()) | ||
.any(|actor| url.eq(&actor)) | ||
{ | ||
Err(AppError::new( | ||
format!("blocked actor: {}", url), | ||
None, | ||
Some(StatusCode::BAD_REQUEST), | ||
)) | ||
} else { | ||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.