add: check ip ban endpoint
This commit is contained in:
parent
8786cb4781
commit
e78c43ab62
8 changed files with 68 additions and 6 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3320,7 +3320,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tetratto-core"
|
name = "tetratto-core"
|
||||||
version = "12.0.0"
|
version = "12.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
"base16ct",
|
"base16ct",
|
||||||
|
|
|
@ -72,6 +72,25 @@ export default function tetratto({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function check_ip(ip) {
|
||||||
|
if (!api_key) {
|
||||||
|
throw Error("No API key provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return api_promise(
|
||||||
|
json_parse(
|
||||||
|
await (
|
||||||
|
await fetch(`${host}/api/v1/bans/${ip}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Atto-Secret-Key": api_key,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).text(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async function query(body) {
|
async function query(body) {
|
||||||
if (!api_key) {
|
if (!api_key) {
|
||||||
throw Error("No API key provided.");
|
throw Error("No API key provided.");
|
||||||
|
@ -285,6 +304,7 @@ export default function tetratto({
|
||||||
api_key,
|
api_key,
|
||||||
// app data
|
// app data
|
||||||
app,
|
app,
|
||||||
|
check_ip,
|
||||||
query,
|
query,
|
||||||
insert,
|
insert,
|
||||||
update,
|
update,
|
||||||
|
|
|
@ -1,12 +1,34 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
State, get_user_from_token,
|
get_app_from_key, get_user_from_token,
|
||||||
model::{ApiReturn, Error},
|
model::{ApiReturn, Error},
|
||||||
routes::api::v1::CreateIpBan,
|
routes::api::v1::CreateIpBan,
|
||||||
|
State,
|
||||||
};
|
};
|
||||||
use axum::{Extension, Json, extract::Path, response::IntoResponse};
|
use axum::{extract::Path, http::HeaderMap, response::IntoResponse, Extension, Json};
|
||||||
use crate::cookie::CookieJar;
|
use crate::cookie::CookieJar;
|
||||||
use tetratto_core::model::{addr::RemoteAddr, auth::IpBan, permissions::FinePermission};
|
use tetratto_core::model::{addr::RemoteAddr, auth::IpBan, permissions::FinePermission};
|
||||||
|
|
||||||
|
/// Check if the given IP is banned.
|
||||||
|
pub async fn check_request(
|
||||||
|
headers: HeaderMap,
|
||||||
|
Path(ip): Path<String>,
|
||||||
|
Extension(data): Extension<State>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let data = &(data.read().await).0;
|
||||||
|
if get_app_from_key!(data, headers).is_none() {
|
||||||
|
return Json(Error::NotAllowed.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Success".to_string(),
|
||||||
|
payload: data
|
||||||
|
.get_ipban_by_addr(&RemoteAddr::from(ip.as_str()))
|
||||||
|
.await
|
||||||
|
.is_ok(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new IP ban.
|
/// Create a new IP ban.
|
||||||
pub async fn create_request(
|
pub async fn create_request(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
|
|
|
@ -495,6 +495,7 @@ pub fn routes() -> Router {
|
||||||
post(communities::communities::update_membership_role),
|
post(communities::communities::update_membership_role),
|
||||||
)
|
)
|
||||||
// ipbans
|
// ipbans
|
||||||
|
.route("/bans/{ip}", get(auth::ipbans::check_request))
|
||||||
.route("/bans/{ip}", post(auth::ipbans::create_request))
|
.route("/bans/{ip}", post(auth::ipbans::create_request))
|
||||||
.route("/bans/{ip}", delete(auth::ipbans::delete_request))
|
.route("/bans/{ip}", delete(auth::ipbans::delete_request))
|
||||||
// reports
|
// reports
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tetratto-core"
|
name = "tetratto-core"
|
||||||
description = "The core behind Tetratto"
|
description = "The core behind Tetratto"
|
||||||
version = "12.0.0"
|
version = "12.0.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
|
@ -408,6 +408,10 @@ impl DataManager {
|
||||||
|
|
||||||
// check muted phrases
|
// check muted phrases
|
||||||
for phrase in receiver.settings.muted {
|
for phrase in receiver.settings.muted {
|
||||||
|
if phrase.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if data.content.contains(&phrase) {
|
if data.content.contains(&phrase) {
|
||||||
// act like the question was created so theyre less likely to try and send it again or bypass
|
// act like the question was created so theyre less likely to try and send it again or bypass
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
|
|
|
@ -75,6 +75,22 @@ impl DataClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the given IP is IP banned from the Tetratto host. You will only know
|
||||||
|
/// if the IP is banned or not, meaning you will not be shown the reason if it
|
||||||
|
/// is banned.
|
||||||
|
pub async fn check_ip(&self, ip: &str) -> Result<bool> {
|
||||||
|
match self
|
||||||
|
.http
|
||||||
|
.get(format!("{}/api/v1/bans/{}", self.host, ip))
|
||||||
|
.header("Atto-Secret-Key", &self.api_key)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(x) => api_return_ok!(bool, x),
|
||||||
|
Err(e) => Err(Error::MiscError(e.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Query the app's data.
|
/// Query the app's data.
|
||||||
pub async fn query(&self, query: &SimplifiedQuery) -> Result<AppDataQueryResult> {
|
pub async fn query(&self, query: &SimplifiedQuery) -> Result<AppDataQueryResult> {
|
||||||
match self
|
match self
|
||||||
|
|
|
@ -31,9 +31,8 @@ pub fn clean_html(html: String, allowed_attributes: HashSet<&str>) -> String {
|
||||||
.rm_tags(&["script", "style", "link", "canvas"])
|
.rm_tags(&["script", "style", "link", "canvas"])
|
||||||
.add_tag_attributes("a", &["href", "target"])
|
.add_tag_attributes("a", &["href", "target"])
|
||||||
.add_url_schemes(&["atto"])
|
.add_url_schemes(&["atto"])
|
||||||
.clean(&html)
|
.clean(&html.replace("<video ", "<video controls "))
|
||||||
.to_string()
|
.to_string()
|
||||||
.replace("<video loading=", "<video controls loading=")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render markdown input into HTML
|
/// Render markdown input into HTML
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue