mirror of
https://github.com/LemmyNet/activitypub-federation-rust.git
synced 2024-06-01 19:22:47 +00:00
Improve webfinger extraction
This commit is contained in:
parent
1fccae69ae
commit
cbc641561f
|
@ -57,6 +57,7 @@ tower = { version = "0.4.13", optional = true }
|
|||
hyper = { version = "0.14", optional = true }
|
||||
futures = "0.3.28"
|
||||
moka = { version = "0.11.3", features = ["future"] }
|
||||
unicode-properties = "0.1.0"
|
||||
|
||||
[features]
|
||||
default = ["actix-web", "axum"]
|
||||
|
|
|
@ -48,7 +48,7 @@ async fn http_get_user(
|
|||
) -> impl IntoResponse {
|
||||
let accept = header_map.get("accept").map(|v| v.to_str().unwrap());
|
||||
if accept == Some(FEDERATION_CONTENT_TYPE) {
|
||||
let db_user = data.read_local_user(name).await.unwrap();
|
||||
let db_user = data.read_local_user(&name).await.unwrap();
|
||||
let json_user = db_user.into_json(&data).await.unwrap();
|
||||
FederationJson(WithContext::new_default(json_user)).into_response()
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//! # use activitypub_federation::traits::Object;
|
||||
//! # use activitypub_federation::traits::tests::{DbConnection, DbUser, Person};
|
||||
//! async fn http_get_user(Path(name): Path<String>, data: Data<DbConnection>) -> Result<FederationJson<WithContext<Person>>, Error> {
|
||||
//! let user: DbUser = data.read_local_user(name).await?;
|
||||
//! let user: DbUser = data.read_local_user(&name).await?;
|
||||
//! let person = user.into_json(&data).await?;
|
||||
//!
|
||||
//! Ok(FederationJson(WithContext::new_default(person)))
|
||||
|
|
|
@ -6,7 +6,6 @@ use crate::{
|
|||
FEDERATION_CONTENT_TYPE,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::HashMap, fmt::Display};
|
||||
use tracing::debug;
|
||||
|
@ -111,22 +110,39 @@ where
|
|||
/// # Ok::<(), anyhow::Error>(())
|
||||
/// }).unwrap();
|
||||
///```
|
||||
pub fn extract_webfinger_name<T>(query: &str, data: &Data<T>) -> Result<String, Error>
|
||||
pub fn extract_webfinger_name<'i, T>(query: &'i str, data: &Data<T>) -> Result<&'i str, Error>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
// Regex to extract usernames from webfinger query. Supports different alphabets using `\p{L}`.
|
||||
// TODO: would be nice if we could implement this without regex and remove the dependency
|
||||
let result = Regex::new(&format!(r"^acct:([\p{{L}}0-9_]+)@{}$", data.domain()))
|
||||
.map_err(|_| WebFingerError::WrongFormat)
|
||||
.and_then(|regex| {
|
||||
regex
|
||||
.captures(query)
|
||||
.and_then(|c| c.get(1))
|
||||
.ok_or_else(|| WebFingerError::WrongFormat)
|
||||
})?;
|
||||
fn accept_char_name(c: char) -> bool {
|
||||
use unicode_properties::{GeneralCategoryGroup, UnicodeGeneralCategory};
|
||||
|
||||
return Ok(result.as_str().to_string());
|
||||
c == '_' || c.is_digit(10) || c.general_category_group() == GeneralCategoryGroup::Letter
|
||||
}
|
||||
|
||||
let Some(rem) = query.strip_prefix("acct:") else {
|
||||
return Err(WebFingerError::WrongFormat.to_crate_error());
|
||||
};
|
||||
|
||||
let mut rem_iter = rem.char_indices();
|
||||
while let Some((idx, c)) = rem_iter.next() {
|
||||
if c == '@' {
|
||||
assert_eq!(c.len_utf8(), 1);
|
||||
if idx == 0 {
|
||||
return Err(WebFingerError::WrongFormat.into());
|
||||
}
|
||||
|
||||
if &rem[idx + 1..] != data.domain() {
|
||||
return Err(WebFingerError::WrongDomain.into());
|
||||
}
|
||||
|
||||
return Ok(&rem[..idx]);
|
||||
} else if !accept_char_name(c) {
|
||||
return Err(WebFingerError::WrongFormat.into());
|
||||
}
|
||||
}
|
||||
|
||||
return Err(WebFingerError::WrongFormat.into());
|
||||
}
|
||||
|
||||
/// Builds a basic webfinger response for the actor.
|
||||
|
@ -274,15 +290,15 @@ mod tests {
|
|||
request_counter: Default::default(),
|
||||
};
|
||||
assert_eq!(
|
||||
Ok("test123".to_string()),
|
||||
Ok("test123"),
|
||||
extract_webfinger_name("acct:test123@example.com", &data)
|
||||
);
|
||||
assert_eq!(
|
||||
Ok("Владимир".to_string()),
|
||||
Ok("Владимир"),
|
||||
extract_webfinger_name("acct:Владимир@example.com", &data)
|
||||
);
|
||||
assert_eq!(
|
||||
Ok("تجريب".to_string()),
|
||||
Ok("تجريب"),
|
||||
extract_webfinger_name("acct:تجريب@example.com", &data)
|
||||
);
|
||||
Ok(())
|
||||
|
|
|
@ -356,7 +356,7 @@ pub mod tests {
|
|||
pub async fn read_post_from_json_id<T>(&self, _: Url) -> Result<Option<T>, Error> {
|
||||
Ok(None)
|
||||
}
|
||||
pub async fn read_local_user(&self, _: String) -> Result<DbUser, Error> {
|
||||
pub async fn read_local_user(&self, _: &str) -> Result<DbUser, Error> {
|
||||
todo!()
|
||||
}
|
||||
pub async fn upsert<T>(&self, _: &T) -> Result<(), Error> {
|
||||
|
|
Loading…
Reference in a new issue