Use actor address regexp for parsing acct: URI
This commit is contained in:
parent
8b6aef2b7a
commit
0c00dca7d3
2 changed files with 33 additions and 19 deletions
|
@ -197,7 +197,7 @@ impl ActorAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
// See also: USERNAME_RE in models::profiles::validators
|
// See also: USERNAME_RE in models::profiles::validators
|
||||||
const ACTOR_ADDRESS_RE: &str = r"(?P<username>[\w\.-]+)@(?P<instance>[\w\.-]+)";
|
pub const ACTOR_ADDRESS_RE: &str = r"(?P<username>[\w\.-]+)@(?P<instance>[\w\.-]+)";
|
||||||
|
|
||||||
impl FromStr for ActorAddress {
|
impl FromStr for ActorAddress {
|
||||||
type Err = ValidationError;
|
type Err = ValidationError;
|
||||||
|
|
|
@ -2,6 +2,7 @@ use actix_web::{get, web, HttpResponse};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
|
use crate::activitypub::actors::types::{ActorAddress, ACTOR_ADDRESS_RE};
|
||||||
use crate::activitypub::constants::AP_MEDIA_TYPE;
|
use crate::activitypub::constants::AP_MEDIA_TYPE;
|
||||||
use crate::activitypub::identifiers::{
|
use crate::activitypub::identifiers::{
|
||||||
local_actor_id,
|
local_actor_id,
|
||||||
|
@ -18,35 +19,35 @@ use super::types::{
|
||||||
JsonResourceDescriptor,
|
JsonResourceDescriptor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc7565#section-7
|
||||||
|
fn parse_acct_uri(uri: &str) -> Result<ActorAddress, ValidationError> {
|
||||||
|
let uri_regexp = Regex::new(&format!("acct:{}", ACTOR_ADDRESS_RE)).unwrap();
|
||||||
|
let uri_caps = uri_regexp.captures(uri)
|
||||||
|
.ok_or(ValidationError("invalid query target"))?;
|
||||||
|
let actor_address = ActorAddress {
|
||||||
|
username: uri_caps["username"].to_string(),
|
||||||
|
instance: uri_caps["instance"].to_string(),
|
||||||
|
};
|
||||||
|
Ok(actor_address)
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_user_info(
|
async fn get_user_info(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
query_params: WebfingerQueryParams,
|
query_params: WebfingerQueryParams,
|
||||||
) -> Result<JsonResourceDescriptor, HttpError> {
|
) -> Result<JsonResourceDescriptor, HttpError> {
|
||||||
// Parse 'acct' URI
|
let actor_address = parse_acct_uri(&query_params.resource)?;
|
||||||
// https://datatracker.ietf.org/doc/html/rfc7565#section-7
|
if !actor_address.is_local(&instance.host()) {
|
||||||
// See also: ACTOR_ADDRESS_RE in activitypub::actors::types
|
|
||||||
let uri_regexp = Regex::new(r"acct:(?P<user>[\w\.-]+)@(?P<instance>.+)").unwrap();
|
|
||||||
let uri_caps = uri_regexp.captures(&query_params.resource)
|
|
||||||
.ok_or(ValidationError("invalid query target"))?;
|
|
||||||
let username = uri_caps.name("user")
|
|
||||||
.ok_or(ValidationError("invalid query target"))?
|
|
||||||
.as_str();
|
|
||||||
let instance_host = uri_caps.name("instance")
|
|
||||||
.ok_or(ValidationError("invalid query target"))?
|
|
||||||
.as_str();
|
|
||||||
|
|
||||||
if instance_host != instance.host() {
|
|
||||||
// Wrong instance
|
// Wrong instance
|
||||||
return Err(HttpError::NotFoundError("user"));
|
return Err(HttpError::NotFoundError("user"));
|
||||||
}
|
};
|
||||||
let actor_url = if username == instance.host() {
|
let actor_url = if actor_address.username == instance.host() {
|
||||||
local_instance_actor_id(&instance.url())
|
local_instance_actor_id(&instance.url())
|
||||||
} else {
|
} else {
|
||||||
if !is_registered_user(db_client, username).await? {
|
if !is_registered_user(db_client, &actor_address.username).await? {
|
||||||
return Err(HttpError::NotFoundError("user"));
|
return Err(HttpError::NotFoundError("user"));
|
||||||
};
|
};
|
||||||
local_actor_id(&instance.url(), username)
|
local_actor_id(&instance.url(), &actor_address.username)
|
||||||
};
|
};
|
||||||
let link = Link {
|
let link = Link {
|
||||||
rel: "self".to_string(),
|
rel: "self".to_string(),
|
||||||
|
@ -77,3 +78,16 @@ pub async fn get_descriptor(
|
||||||
.json(jrd);
|
.json(jrd);
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_acct_uri() {
|
||||||
|
let uri = "acct:user_1@example.com";
|
||||||
|
let actor_address = parse_acct_uri(uri).unwrap();
|
||||||
|
assert_eq!(actor_address.username, "user_1");
|
||||||
|
assert_eq!(actor_address.instance, "example.com");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue